1.Young GC\Old GC\Full GC的定义
Young GC是年轻代的GC,Old GC就是老年代的GC,Full GC是针对年轻代、老年代、永久代进行的整体的GC。
此外还有几个其他的名词跟他们有重叠的含义,比如Minor GC也可以称之为Young GC,Major GC也可以称之为Old GC,有的人也把Major GC和Full GC划等号,也有人把Full GC和Old GC划等号。
同一概念,Young GC指代年轻代GC,用Old GC指代老年代GC,用Full GC指代年轻代、老年代、永久代共同的GC。
2. Young GC的触发时机
Young GC一般在新生代的Eden区域满了之后就会触发,采用复制算法来回收新生代的垃圾。
3. Old GC和Full GC的触发时机
OldGC的触发时机有以下几种情况:
1、 发生Young GC之前进行检查,如果“老年代可用的连续内存空间” < “新生代历次Young GC后升入老年代的对象总和的平均大小”,说明本次Young GC后可能升入老年代的对象大小,可能超过了老年代当前可用内存空间。
此时必须先触发一次Old GC给老年代腾出更多的内存空间出来,然后再执行 Young GC。
2、 执行 Young GC之后有一批对象要放入老年代,此时老年代就没有足够的内存空间存放这些对象了,此时必须立即触发一次Old GC
3、 老年代内存使用率超过了92%,也要直接触发Old GC,当然这个比例是可以通过参数调整的
总结为一句话,当老年代空间不够了,没法放入更多对象了,这个时候就必须执行Old GC对老年代进行垃圾回收。
此外,一般Old GC很可能就是在Young GC之前触发或者在Young GC之后触发的,所以Old GC一般都会跟一次Young GC关联在一起。
另外一个,当满足上述几种条件时,触发的会是 Full GC,这个Full GC会包含Young GC、Old GC和永久代的GC。
也就是说触发Full GC的时候,可能会去回收年轻代、老年代和永久代三个区域的垃圾对象。
4. 永久代满了怎么办?
上面说了,Full GC几个条件满足,触发Full GC的时候会带上对新生代的Young GC,以及对老年代的Full GC,还会有针对永久代的GC。所以假如存放类信息、常量池的永久代满了之后, 就会触发一次Full GC。
这样Full GC执行的时候,就会顺带把永久代中的垃圾给回收了,但是永久代中的垃圾一般是很少的,因为里面存放的都是一些类,还有常量池之类的东西,这些东西通常来说是不需要回收的。如果永久代真的放满了,回收之后发现没腾出来更多的地方,此时只能抛出内存不够的异常了。
也就是说,在抛出OOM之前,老年代或永久代必然经过一次GC回收。