minor gc和full gc的触发条件

鉴于现在各种GC名称已经叫混了,首先声明一下Minor GC和Full GC的定义:

Minor GC: 回收区域只包括年轻代(Eden, From)。

Full GC: 回收区域包括整个堆区和方法区。

注:有的人把Major GC和Full GC混为一谈,我更愿意认为Major GC等价于Old GC,目前只有CMS收集器存在只回收老年代的情况。

Minor GC触发条件:

  1. Eden空间不足。

注:Parallel Scavenge垃圾收集器框架(Parallel Scavenge+PS MarkSweep或者Parallel Scavenge + Parallel Old)有个小的实现细节,每次Full GC之前都会先进行一次Minor GC。

full gc触发条件:

  1. 大对象直接进入老年代时老年代连续空间不足
  2. 年轻代对象经过Minor GC晋升老年代时老年代连续空间不足
  3. 在发生minor gc之前虚拟机将会检查老年代剩余空间是否大于新生代对象总空间(考虑最坏情况,新生代所有对象都晋升),如果条件成立,那么可以确保这次minor gc是安全的。否则,虚拟机会虚拟机参数HandlePromotionFailure的设置值是够允许冒险(允许:-XX:+HandlePromotionFailure,不允许:-XX:-HandlePromotionFailure)。如果允许那么虚拟机会查看老年代剩余空间是否大于历次晋升老年代对象大小的平均值,当老年代剩余空间大于历次晋升大小平均值时虚拟机将冒险进行一次minor gc,如果当前minor gc晋升对象的大小总和远超历史平均值老年代接不下的话将导致空间分配担保失败,从而再执行一次full gc;如果老年代空间小于历次晋升平均值或者-XX:HandlePromotionFailure不允许冒险都将放弃minor gc改为full gc。JDK 6 UPDATE 24以后HandlePromotionFailure参数失效了,实测在JDK1.8中已经移除了这个参数(具体从哪个版本开始移除还有待考证,Non-Stable参数本来就是官方送给用户的"不提供技术支持,只作为实验性质"的附赠品,随时可能被移除),改为只要老年代连续空间总大小大于历次晋升平均大小就进行Minor GC,否则进行Full GC。(相当于默认为真了)
  4. 方法区空间不足(JDK 8开始彻底的去永久代(Perm Gen)改用在本地内存(Native Memory)实现的元空间(Metaspace)代替,一般很难出现方法区内存不足的情况了)。
  5. CMS垃圾收集器发生Concurrent Mode Failure后将暂停用户线程,启用Serial Old垃圾收集器进行Full GC。
  6. G1垃圾收集器Mixed GC收集时当收集速度赶不上内存分配速度导致老年代被填满(G1垃圾收集器只有触发Mixed GC才会回收老年代,而Mixed GC除了回收年轻代外只回收部分回收效益较高的老年代,正常情况下G1不存在Full GC),也会触发串行垃圾收集器进行Full GC作为担保机制。
  7. 调用System.gc()方法将建议JVM执行Full GC,不保证执行

你可能感兴趣的:(minor gc和full gc的触发条件)