通过一段代码在 JVM 中运行情况来分析:
public class Kafka {
private static ReplicaFetcher fetcher = new ReplicaFetcher();
public static void main(String[] args){
loadReplicasFromDisk();
while(true){
fetchReplicasFromRemote();
Thread.sleep(1000);
}
}
private static void loadReplicasFromDisk(){
ReplicaManager replicaManager = new ReplicaManager();
replicaManager.load();
}
private static void fetchReplicasFromRemote(){
fetcher.fetch();
}
}
1. 什么是年轻代、老年代、永久代?
- 年轻代:
- 像 ReplicaManager 对象,在方法中被创建的对象实例,在方法执行完后,就没有任何变量引用这个对象,很快被垃圾回收掉;
- 代码中,绝大多数对象都是像这样存活周期极短,都被放在 Java 堆内存的年轻代;
- 老年代:
- 像 ReplicaFetcher 对象,被类的静态变量引用的,他开始会放在年轻代,但是随着长期的被引用,它会被转移到老年代;
- 代码中,少数对象会有很长的生命周期,需要不停的被使用,都被放在 Java 堆内存的老年代;
- 永久代:
- 像 Kafka 类,它的类信息会放在方法区,这个方法区就是永久代;
- 方法区,即所谓的永久代,存放一些类信息的;
2. Java 堆内存为什么要分成年轻代和老年代?
- 和垃圾回收有关;
- 年轻代的对象生命周期短,老年代的生命周期长,所以需要将内存堆划分成两个不同区域,各自使用不同的垃圾回收算法;