41

ZGC什么时候进行垃圾回收

 5 years ago
source link: http://www.jianshu.com/p/b5fb06ffbb90?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

对ZGC还不怎么了解的同学,可以先看看这篇文章 ZGC,一个超乎想象的垃圾收集器

以往的一些GC算法,比如CMS、G1,采用分代的思想对堆内存进行划分,对应的GC行为也可以分为Young GC、Old GC 和 FGC。

但是在ZGC算法中,并没有分代的概念,所以就不存在Young GC、Old GC,所有的GC行为都是Full GC。

那ZGC的垃圾回收行为什么时候会进行?

撸了下源码,已经准确定位到触发ZGC的逻辑,位于zDirector.cpp文件。

虚拟机启动时,会启动一个线程执行如下逻辑:

void ZDirector::run_service() {
  // Main loop
  while (_metronome.wait_for_tick()) {
    sample_allocation_rate();
    const GCCause::Cause cause = make_gc_decision();
    if (cause != GCCause::_no_gc) {
      ZCollectedHeap::heap()->collect(cause);
    }
  }
}

其中 _metronome.wait_for_tick() 每间隔100ms返回一次,意味着每100ms执行一次 make_gc_decision() ,决定是否执行ZGC。

make_gc_decision() 中提供了4种策略,只要满足其中1个策略就可以触发ZGC。

rule_timer

第一个策略,从行为表现上,我把它叫做是周期性GC,默认是不生效的,但是如果配置 -XX:ZCollectionInterval=1(单位是秒),那么每隔1s,就会执行一次ZGC,太暴力了。

rule_warmup

JVM启动之后,如果一直没有发生过GC,那么会在堆内存使用超过10%、20%、30%时,分别触发一次GC,这样做是为了收集一些GC相关的数据,为后面的条件规则提供数据支撑。

rule_allocation_rate

根据对象分配速率决定是否GC。

如果当前的可用堆内存,根据估计出来的对象最大分配速率,很快会被耗尽,则执行一次GC,这种策略一般在qps很高、对象分配很快时会被触发。

rule_proactive

这个策略是积极主动型的。

如果能够接受因为GC引起的应用吞吐量下降,那么就触发GC,这个策略允许我们降低堆内存,并且在堆内存还有很多剩余空间时,执行引用处理,具体的条件是:

1、自从上次GC之后,堆的使用量至少涨了10%

2、自从上次GC之后,已经过去5分钟没有发生GC

这有助于在对象分配率非常低的应用程序时避免多余的GC.

这4种都是在还有空闲内存的时候就执行GC的策略,那如果垃圾回收的速度赶不上对象分配的速率,怎么办?

这个时候,分配对象的应用线程,只能停下来,等待垃圾对象的回收,如果回收掉一部分内存,就可以直接拿到用了,不需要等垃圾回收执行完成。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK