文章>ZGC什么时候会进行垃圾回收>

ZGC什么时候会进行垃圾回收

占小狼
gc
zgc
2周前

以往的一些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。

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

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

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

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

  1. 自从上次GC之后,堆的使用量至少涨了10%
  2. 自从上次GC之后,已经过去5分钟没有发生GC

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

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

这个时候,分配对象的应用线程只能停下来,等待垃圾对象的回收。

2334 阅读
请先登录,再评论

评论列表

言风2周前

ZGC在回收的时候,是否也会STW呢?ZGC相比较分代回收算法,有什么优势呢?
期待大佬的解答😋

言风1周前
回复 csyangchsh:

感谢解答,期待学习以后分享下🍺🍺

回复
csyangchsh1周前
回复 言风:

Azul C4我不了解,其他GC算法实现应该都有STW,gc roots的枚举必须STW,不然没法保证正确性。

回复
csyangchsh1周前
回复 言风:

ZGC还是会有STW的,只不过时间非常短。这个STW的时间和root set成正比,不会随着堆或者live object set增大而增大。STW后Mark和Relocate都是并发执行的。可以看下Per Lidén的演讲。

回复