目录
在上一篇《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(¬Older, 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(),
¬Older,
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, "