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