什么时候触发GC

Young GC—-针对年轻代

当Eden区满了的时候,会触发Young GC

Full GC—-针对整个堆

1. 在发生Young GC的时候,虚拟机会检测之前每次晋升到老年代的平均大小是否大于年老代的剩余空间,如果大于,则直接进行Full GC;

2. 如果小于,但设置了Handle PromotionFailure,那么也会执行Full GC。promotion failed是在进行Minor GC时,survivor space放不下、对象只能放入老年代,而此时老年代也放不下造成的。

3. 永久代空间不足,会触发Full GC

4. System.gc()也会触发Full GC

5. 堆中分配很大的对象

所谓大对象,是指需要大量连续内存空间的java对象,例如很长的数组,此种对象会直接进入老年代,而老年代虽然有很大的剩余空间,但是无法找到足够大的连续空间来分配给当前对象,此种情况就会触发JVM进行Full GC。为了解决这个问题,CMS垃圾收集器提供了一个可配置的参数,即-XX:+UseCMSCompactAtFullCollection开关参数,用于在“享受”完Full GC服务之后额外免费赠送一个碎片整理的过程,内存整理的过程无法并发的,空间碎片问题没有了,但提顿时间不得不变长了,JVM设计者们还提供了另外一个参数 -XX:CMSFullGCsBeforeCompaction,这个参数用于设置在执行多少次不压缩的Full GC后,跟着来一次带压缩的。

6. CMS GC concurrent mode failure

concurrent mode failure是在执行CMS GC的过程中同时有对象要放入老年代,而此时老年代空间不足造成的(有时候“空间不足”是CMS GC时当前的浮动垃圾过多导致暂时性的空间不足触发Full GC)

CMS GC—-针对年老代

  1. 配置了-XX:CMSInitiatingOccupancyFraction=75和-XX:+UseCMSInitiatingOccupancyOnly,设定CMS在对内存占用率达到75%的时候开始GC

  2. 配置了-XX:+CMSClassUnloadingEnabledCMSInitiatingPermOccupancyFraction=80%,即:Perm Gen的使用达到一定的比率,默认为92%

  3. 配置了-XX:+ExplicitGCInvokesConcurrent,未配置-XX:+DisableExplicitGC的情况下,显示调用了System.gc()

CMS在并发模式工作的时候是只收集old gen的。但一旦并发模式失败(发生concurrent mode failure)就有选择性的会进行全堆收集,也就是退回到full GC。

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/tech/opensource/194808.html

(0)
上一篇 2021年11月16日 08:13
下一篇 2021年11月16日 08:22

相关推荐

发表回复

登录后才能评论