Silentdoer

导航

Java Young GC和Old GC的概念

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

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

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

 

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

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

 

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

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

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

所以如果年轻代的对象内存占用达到600M后就会触发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)【但是从原理上来讲,Young GC也是stw才对,Young GC时显然不能创建对象那么快】

 

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

但是jdk21的ZGC是分代了的(需要配置开启:-XX:+UseZGC -XX:+ZGenerational),也有年轻代,老年代的概念;年轻代会GC的更频繁;

年轻代和老年代是独立进行收集和GC的

 

ZGC之所以会影响性能,是因为它在创建对象的时候会做更多额外的工作,方便后续的快速的GC

posted on 2023-11-22 09:35  Silentdoer  阅读(222)  评论(0编辑  收藏  举报