Java Young GC和Old GC的概念

发布时间 2023-11-22 09:42:58作者: Silentdoer

1.java内存模型里有年轻代和老年代的概念;

年轻代:顾名思义其实就是新创建的堆内存对象都会在年轻代里;

老年代:就是年轻代里的对象经过一定时间后"变老"了,进入老年代;

 

那年轻代的对象 什么时候 进入老年代 呢?

默认情况下是 对象 在年轻代 的GC 15次后 仍然存活(即不是那种创建后很快就释放不用了),那么这个对象就会从年轻代移动到老年代;

 

而GC分为年轻代GC和老年代GC,也是因为堆内存被分为了年轻代和老年代;

因此年轻代和老年代都有各自的内存大小,比如可以简单的理解为 总堆内存是1G的话,配置了年轻代内存是800M,则老年代内存是224M;

因此,如果我们频繁创建对象并且立刻不再使用(类似var a = new ComplexObj();a = null;这样这个对象就是已经可以释放的了),这些对象是都会先到达年轻代;

所以如果年轻代的对象内存占用达到800M后就会触发Young GC;

而如果Young GC在执行了15次后(也可以配置其他值-XX:MaxTenuringThreshold=10)仍然没有释放(比如var a = ComplexObj(); globalList.add(a)就会将对象放到全局list里使得a不会被gc释放),则这个对象会放到老年代里;

 

同样的,老年代内存肯定也是会耗尽的(比如globalList.add(obj);add了很多对象),所以就会产生Old GC(貌似也叫Major GC);

 

GC是有耗时的,可以采集到这个指标;对于大多数程序,一般是young空间要大于old空间;而对于一些状态程序则old空间会大一些(比如大数据中间件)

 

而Java里的Stop The world一般是Full GC和Major GC(Full GC是同时产生了Young GC和Old GC)

 

ZGC则直接没有了年轻代、老年代的区分(当然有Region的概念,有点像磁盘划分时的单元大小,防止磁盘碎片的),而且它在哪怕对上百G的数据GC时间都是10ms以下;