zl程序教程

您现在的位置是:首页 >  其它

当前栏目

一文搞懂Y-GC和Full GC的触发条件

条件 一文 触发 搞懂 GC full
2023-09-27 14:19:47 时间

1 Young GC触发时机

一般在新生代Eden区满后触发,采用复制算法回收新生代垃圾。

2 Old GC和Full GC的触发时机

2.1

发生Young GC前检查,若

老 年 代 可 用 连 续 内 存 空 间 < 新 生 代 历 次 Y o u n g G C 后 升 入 老 年 代 的 对 象 总 和 的 平 均 大 小 老年代可用连续内存空间 < 新生代历次Young GC后升入老年代的对象总和的平均大小 <YoungGC

说明本次Y-GC后,可能升入老年代的对象大小超过老年代当前可用内存空间,此时必须先触发一次Old GC给老年代腾出空间,再执行Young GC。

2.2 执行Y-GC后,有一批对象需要放入老年代

但此时老年代无足够内存空间存放这些对象,此时必须立即触发一次Old GC。

2.3 老年代内存使用率超过92%,直接触发Old GC

这个比例是可以通过参数调整的。

Old GC执行时,一般都会带上一次Y-GC,一般Old GC很可能就是在Young GC之前或之后触发,所以自然Old GC一般都会跟一次Young GC连带关联在一起了。

很多JVM实现里,其实在上述几种条件达到时,他触发的实际上就是Full GC,其实满足上述一些条件时,在GC日志中看到的就是Full GC字样。

但是这个东西其实没办法给大家一个准确的定义,说到底触发Full GC的时候,是先执行Young GC?还是先执行Old GC?不同Full GC触发条件不一样,而且不同JVM版本实现也不同。

所以只能概括:上述条件满足时触发Full GC,Full GC一般会带上一次Young GC 去回收新生代,同时也会有Old GC也回收老年代,还会去回收永久代。

永久代满了咋办?

假如存放类信息、常量池的永久代满了后,就会触发一次Full GC。

这样Full GC执行时,就会顺带把永久代中的垃圾给回收了,但永久代中的垃圾一般很少,因为里面存放的都是一些类,还有常量池之类的东西,这些东西通常无需回收。如果永久代真的放满了,回收之后发现没腾出来更多的地方,此时只能抛出内存不够异常。