Java GC机制小结之CMS触发条件

CMS GC是Java的一种并发标记清除收集器,旨在减少停顿时间。它分为Background Collector和Foreground Collector,前者通过多种条件判断触发,如内存使用率、系统请求等;后者在空间不足时直接触发。在Java 9中,Foreground Collector被移除。CMS GC的触发条件涉及Old Gen使用率、Young GC失败、MetaSpace、参数配置等多个因素。
摘要由CSDN通过智能技术生成

CMS GC是Mostly Concurrent收集器,全称为Concurrent Mark Sweep GC,是一种以获取最短停顿时间为目标的收集器。CMS的设计初衷和目的是为了消除Parallel GC和Serial Old GC在Full GC时长时间的停顿,从名字(Mark Sweep)上就可以看出,CMS GC是基于标记-清除算法实现,这也导致服务长时间运行会有严重的内存碎片化问题。另外,算法在实现上也会比较复杂。

CMS GC从触发机制上可以分为Background Collector和Foregroud Collector(其实还有Mark-Sweep-Compact Collector,MSC Collector,也就是Java GC机制小结所示图片中,位于Serial Old下方的MSC,只是该算法基本可以认为就是Serial Old GC)。值的注意的是Foreground Collector已经在Java 9中被移除了。

Background Collector

Backgroud collector是通过CMS后台线程不断的去扫描,过程中主要是判断是否符合background collector的触发条件,一旦有符合的情况,就会进行一次background的collect。

void ConcurrentMarkSweepThread::run() {
... // 省略
  while (!_should_terminate) {
    sleepBeforeNextCycle();
    if (_should_terminate) break;
    GCCause::Cause cause = _collector->_full_gc_requested ?
      _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
    _collector->collect_in_background(false, cause);
  }
... // 省略
}

每次扫描过程中,先等CMSWaitDuration(默认值是2s)时间,然后再去进行一次shouldConcurrentCollect判断,看是否满足CMS background collector的触发条件。

void ConcurrentMarkSweepThread::sleepBeforeNextCycle() {
  while (!_should_terminate) {
    if (CMSIncrementalMode) {
      icms_wait();
      if(CMSWaitDuration >= 0) {
        // Wait until the next synchronous GC, a concurrent full gc
        // request or a timeout, whichever is earlier.
        wait_on_cms_lock_for_scavenge(CMSWaitDuration);
      }
      return;
    } else {
      if(CMSWaitDuration >= 0) {
        // Wait until the next synchronous GC, a concurrent full gc
        // request or a timeout, whichever is earlier.
        wait_on_cms_lock_for_scavenge(CMSWaitDuration);
      } else {
        // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently
        wait_on_cms_lock(CMSCheckInterval);
      }
    }
    // Check if we should start a CMS collection cycle
    if (_collector->shouldConcurrentCollect()) {
      return;
    }
    // .. collection criterion not yet met, let's go back
    // and wait some more
  }
}

让我们来看看shouldConcurrentCollect方法中有哪些条件呢?

bool CMSCollector::shouldConcurrentCollect() {
  // 第一种触发情况,是否并行Full GC
  if (_full_gc_requested) {
    if (Verbose && PrintGCDetails) {
      gclog_or_tty->print_cr("CMSCollector: collect because of explicit "
                             " gc request (or gc_locker)");
    }
    return true;
  }

  // For debugging purposes, change the type of collection.
  // If the rotation is not on the concurrent collection
  // type, don't start a concurrent collection.
  NOT_PRODUCT(
    if (RotateCMSCollectionTypes &&
        (_cmsGen->debug_collection_type() !=
          ConcurrentMarkSweepGeneration::Concurrent_collection_type)) {
      assert(_cmsGen->debug_collection_type() !=
        ConcurrentMarkSweepGeneration::Unknown_collection_type,
        "Bad cms collection type");
      return false;
    }
  )

  FreelistLocker x(this);
  // ------------------------------------------------------------------
  // Print out lots of information which affects the initiation of
  // a collection.
  if (PrintCMSInitiationStatistics && stats().valid()) {
    gclog_or_tty->print("CMSCollector shouldConcurrentCollect: ");
    gclog_or_tty->stamp();
    gclog_or_tty->cr();
    stats().print_on(gclog_or_tty);
    gclog_or_tty->print_cr("time_until_cms_gen_full %3.7f",
      stats().time_until_cms_gen_full());
    gclog_or_tty->print_cr("free=" SIZE_FORMAT, _cmsGen->free());
    gclog_or_tty->print_cr("contiguous_available=" SIZE_FORMAT,
                           _cmsGen->contiguous_available());
    gclog_or_tty->print_cr("promotion_rate=%g", stats().promotion_rate());
    gclog_or_tty-&
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值