Hotspot 垃圾回收之CMSCollector(二) 源码解析

本文深入解析Hotspot CMS垃圾回收器的InitialMarking阶段,包括checkpointRootsInitial、CMSParInitialMarkTask、CMSConcMarkingTask等关键步骤。文章详细阐述了年轻代和根节点的并行标记过程,以及并发标记任务的执行逻辑,为理解CMS并发模式提供了源码层面的洞察。
摘要由CSDN通过智能技术生成

     目录

1、checkpointRootsInitial

2、CMSParMarkTask

3、CMSParInitialMarkTask

4、Par_MarkRefsIntoClosure

5、CLDToOopClosure 

6、markFromRoots

7、CMSConcMarkingTask

7.1、work

7.2 coordinator_yield / reset


在上一篇《Hotspot 垃圾回收之CMSCollector(一) 源码解析》中讲解了由VMThread执行的前台GC和由CMSThread执行的后台GC的整体逻辑,从本篇开始就逐步讲解每个GC步骤的实现细节。

1、checkpointRootsInitial

     checkpointRootsInitial方法用于处理CMS GC的第一个步骤,InitialMarking,其并行执行的实现都封装在CMSParInitialMarkTask中,此方法只是做必要的检查和准备工作,其实现如下:

void CMSCollector::checkpointRootsInitial(bool asynch) {
  assert(_collectorState == InitialMarking, "Wrong collector state");
  //校验当前线程是否正确
  check_correct_thread_executing();
  TraceCMSMemoryManagerStats tms(_collectorState,GenCollectedHeap::heap()->gc_cause());
  
  //保存堆内存和元空间使用情况
  save_heap_summary();
  //_gc_tracer_cm记录上面保存的内存使用情况
  report_heap_summary(GCWhen::BeforeGC);

  ReferenceProcessor* rp = ref_processor();
  SpecializationStats::clear();
  assert(_restart_addr == NULL, "Control point invariant");
  if (asynch) {
    //如果是异步的,即后台GC
    //获取bitMapLock锁
    MutexLockerEx x(bitMapLock(),
                    Mutex::_no_safepoint_check_flag);
    checkpointRootsInitialWork(asynch);
    //允许查找Reference实例,两个参数是判断是否校验ReferenceProcessor状态的
    rp->enable_discovery(true /*verify_disabled*/, true /*check_no_refs*/);
    _collectorState = Marking;
  } else {
    //校验ReferenceProcessor的属性是否正确
    assert(!rp->discovery_is_atomic(),
           "incorrect setting of discovery predicate");
    assert(!rp->discovery_enabled(), "genCollectedHeap shouldn't control "
           "ref discovery for this generation kind");
    // already have locks
    checkpointRootsInitialWork(asynch);
    //允许查找Reference实例
    rp->enable_discovery(true /*verify_disabled*/, false /*verify_no_refs*/);
    _collectorState = Marking;
  }
  SpecializationStats::print();
}

#ifndef PRODUCT
void CMSCollector::check_correct_thread_executing() {
  Thread* t = Thread::current();
  //只能是VMThread 或者 CMS thread
  assert(t->is_ConcurrentGC_thread() || t->is_VM_thread(),
         "Unexpected thread type");
  //_foregroundGCShouldWait为true,则只能是CMS Thread
  if (_foregroundGCShouldWait) {
    // We cannot be the VM thread
    assert(t->is_ConcurrentGC_thread(),
           "Should be CMS thread");
  } else {
    if (t->is_ConcurrentGC_thread()) {
      ///_foregroundGCShouldWait为false,且是CMS Thread,则状态必须是这两种
      assert(_collectorState == InitialMarking ||
             _collectorState == FinalMarking,
             "Should be a stop-world phase");
      // The CMS thread should be holding the CMS_token.
      assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(),
             "Potential interference with concurrently "
             "executing VM thread");
    }
  }
}
#endif

void CMSCollector::report_heap_summary(GCWhen::Type when) {
  _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary);
  _gc_tracer_cm->report_metaspace_summary(when, _last_metaspace_summary);
}

void CMSCollector::checkpointRootsInitialWork(bool asynch) {
  //校验当前JVM处于安全点
  assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
  assert(_collectorState == InitialMarking, "just checking");

  //校验已经获取了bitMapLock锁
  assert_lock_strong(bitMapLock());
  //校验markBitMap已清空
  assert(_markBitMap.isAllClear(), "was reset at end of previous cycle");

  //设置verifying属性和root_scanning_option属性
  setup_cms_unloading_and_verification_state();

  if (UseAdaptiveSizePolicy) {
    //通知InitialWork开始
    size_policy()->checkpoint_roots_initial_begin();
  }

  //CMSPLABRecordAlways默认为true,表示总是记录survivor区PLAB的边界
  if (_survivor_plab_array != NULL && !CMSPLABRecordAlways) {
    reset_survivor_plab_arrays();
  }

  ResourceMark rm;
  HandleMark  hm;

  MarkRefsIntoClosure notOlder(_span, &_markBitMap);
  GenCollectedHeap* gch = GenCollectedHeap::heap();
  
  //校验markStack和_overflow_list是空的
  verify_work_stacks_empty();
  //校验_preserved_mark_stack和_preserved_oop_stack是空的
  verify_overflow_empty();

  //遍历所有JavaThread,让其TLAB不能被用于分配对象
  gch->ensure_parsability(false);  // fill TLABs, but no need to retire them
  //更新各代包含的Space的save_mark_word
  gch->save_marks();

  //设置enqueuing_is_done属性为false,为true表示Reference实例已经查找并处理完毕
  ref_processor()->set_enqueuing_is_done(false);

  //另外保存所有新创建的ClassLoaderData
  ClassLoaderDataGraph::remember_new_clds(true);

  //清除所有ClassLoaderData的claimed标识,该标识表示该ClassLoaderData已经遍历过了
  ClassLoaderDataGraph::clear_claimed_marks();

  if (CMSPrintEdenSurvivorChunks) {
    print_eden_and_survivor_chunk_arrays();
  }

  {
    COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
    //CMSParallelInitialMarkEnabled默认为true,表示是否允许并行的InitialMark
    if (CMSParallelInitialMarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
      // The parallel version.
      FlexibleWorkGang* workers = gch->workers();
      assert(workers != NULL, "Need parallel worker threads.");
      int n_workers = workers->active_workers();
      CMSParInitialMarkTask tsk(this, n_workers);
      gch->set_par_threads(n_workers);
      //计算年轻代三个区并行遍历所需的任务数
      initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
      if (n_workers > 1) {
        GenCollectedHeap::StrongRootsScope srs(gch);
        //并发执行CMSParInitialMarkTask任务
        workers->run_task(&tsk);
      } else {
        GenCollectedHeap::StrongRootsScope srs(gch);
        tsk.work(0);
      }
      gch->set_par_threads(0);
    } else {
      //串行执行逻辑
      CLDToOopClosure cld_closure(&notOlder, true);
      gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
      gch->gen_process_roots(_cmsGen->level(),
                             true,   // younger gens are roots
                             true,   // activate StrongRootsScope
                             GenCollectedHeap::ScanningOption(roots_scanning_options()),
                             should_unload_classes(),
                             &notOlder,
                             NULL,
                             &cld_closure);
    }
  }

  assert(_modUnionTable.isAllClear(),
       "Was cleared in most recent final checkpoint phase"
       " or no bits are set in the gc_prologue before the start of the next "
       "subsequent marking phase.");

  assert(_ct->klass_rem_set()->mod_union_is_clear(), "Must be");

  //保存cmsSpace的_sweep_limit属性
  save_sweep_limits();
  if (UseAdaptiveSizePolicy) {
    size_policy()->checkpoint_roots_initial_end(gch->gc_cause());
  }
  verify_overflow_empty();
}

//设置verifying属性和root_scanning_option属性
void CMSCollector::setup_cms_unloading_and_verification_state() {
  //这些verify选项默认配置下都是false
  const  bool should_verify =   VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC
                             || VerifyBeforeExit;
  const  int  rso           =   GenCollectedHeap::SO_AllCodeCache;

  // We set the proper root for this CMS cycle here.
  if (should_unload_classes()) {   // Should unload classes this cycle
    //如果需要卸载类,则移除标识SO_AllCodeCache
    remove_root_scanning_option(rso);  // Shrink the root set appropriately
    set_verifying(should_verify);    // Set verification state for this cycle
    return;                            // Nothing else needs to be done at this time
  }

  assert(!should_unload_classes(), "Inconsitency!");
  //不需要卸载类,则添加标识SO_AllCodeCache
  add_root_scanning_option(rso);

  if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
    set_verifying(true);
  } else if (verifying() && !should_verify) {
    set_verifying(false);
    remove_root_scanning_option(rso);
  }
}

bool should_unload_classes() const {
    return _should_unload_classes;
  }

void remove_root_scanning_option(int o) { _roots_scanning_options &= ~o;  }

void set_verifying(bool v) { _verifying = v; }

void add_root_scanning_option(int o)    { _roots_scanning_options |= o;   }

bool verifying() const { return _verifying; }

bool CMSCollector::overflow_list_is_empty() const {
  assert(_num_par_pushes >= 0, "Inconsistency");
  if (_overflow_list == NULL) {
    assert(_num_par_pushes == 0, "Inconsistency");
  }
  return _overflow_list == NULL;
}

void CMSCollector::verify_work_stacks_empty() const {
  assert(_markStack.isEmpty(), "Marking stack should be empty");
  assert(overflow_list_is_empty(), "Overflow list should be empty");
}

void CMSCollector::verify_overflow_empty() const {
  assert(overflow_list_is_empty(), "Overflow list should be empty");
  assert(no_preserved_marks(), "No preserved marks");
}

bool CMSCollector::no_preserved_marks() const {
  return _preserved_mark_stack.is_empty() && _preserved_oop_stack.is_empty();
}

//初始化年轻代三个区的par_seq_tasks属性
void
CMSCollector::
initialize_sequential_subtasks_for_young_gen_rescan(int n_threads) {
  assert(n_threads > 0, "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值