java Minor GC、 Full GC之间的区别
Java Minor GC、 Full GC之间的区别
Minor GC
Minor GC 指发生在新生代(分为Eden区和Survivor区)的一系列垃圾回收操作,当新生代内存不足,无法给新的新生代对象分配空间的时候,就会触发Minor GC。Minor GC的具体触发条件:
jvm在进行Minor GC之前会先判断老年代最大的连续可用空间是否大于新生代所有对象的总空间,如果大于的话直接执行Minor GC,如果小于,判断是否开启HandlerPromotionFailure,没有开启则直接进行Full GC。如果开启了HanlerPromotionFailure, JVM会判断老年代的最大连续内存空间是否大于历次晋升(晋级老年代对象的平均大小)平均值的大小,如果小于直接执行Full GC,若是大于就直接进行Minor GC。
在发生Minor GC之前,jvm检查老年代最大的连续空间是否大于新生代的所有对象的空间,如果是的话,那么Minor GC是安全的,可以直接进行。小于的话,则会查看HanlerPromotionFailure 的设置值,如果为允许的话,jvm会继续检查老年代最大可用的连续内存空间是否大于历次晋级到老年代对象的平均大小,如果大于就尝试一次Minor GC, 如果老年代最大可用的连续内存空间小于历次晋级到老年代对象的平均大小,或者HanlerPromotionFailure的设置值为不允许,就要进行一次Full GC。jvm就是通过这样的方式判断是否能安全地进行Minor GC,如果HanlerPromotionFailure的设置值为不允许,或者老年代最大可用的连续内存空间是否大于历次晋级到老年代对象的平均大小,这都是不能安全进行Minor GC的情况,这个时候jvm就会进行一次Full GC。(相当于老年代的内存给新生代做担保?无法担保的话就会触发Full GC)
Full GC
Full GC就是针对整个堆空间的全局性GC,包括新生代和老生代。Full GC触发条件:
老年代的空间不足
如果创建了一个占用内存过大的对象,新生代的eden区放不下这个对象,会直接保存在老年代中,就会触发Full GC。发生这种现象的前提是创建了过大的对象,所以不创建过大对象可以避免Full GC的触发
出现promotion failure
如果年轻代的Survivor区中存活的对象的年龄达到了设定值,会先将Survivor区中的对象先拷贝到老年代,但是如果老年代空间不足,就会发生promotion failure的情况,这个时候也会触发Full GC。
统计年轻代对象晋升到老年代的平均总大小大于老年代的空闲空间
在发生年轻代对象晋升到老年代的平均总大小大于老年代的空闲空间的情况下,jvm会判定新生代的晋升为不安全行为,不会再执行年轻代的晋升,而是执行Full GC。