-XX:+UseSerialGC
指定使用Serial GC
因此,对应使用的堆类型为GenCollectedHeap
void GenCollectedHeap::process_roots(ScanningOption so,
OopClosure* strong_roots,
CLDClosure* strong_cld_closure,
CLDClosure* weak_cld_closure,
CodeBlobToOopClosure* code_roots) {
// General roots.
assert(code_roots != NULL, "code root closure should always be set");
ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure);
// Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway
CodeBlobToOopClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
// 此处为入口,遍历栈帧中的OopMapSet
Threads::oops_do(strong_roots, roots_from_code_p);
OopStorageSet::strong_oops_do(strong_roots);
if (so & SO_ScavengeCodeCache) {
assert(code_roots != NULL, "must supply closure for code cache");
// We only visit parts of the CodeCache when scavenging.
ScavengableNMethods::nmethods_do(code_roots);
}
if (so & SO_AllCodeCache) {
assert(code_roots != NULL, "must supply closure for code cache");
// CMSCollector uses this to do intermediate-strength collections.
// We scan the entire code cache, since CodeCache::do_unloading is not called.
CodeCache::blobs_do(code_roots);
}
// Verify that the code cache contents are not subject to
// movement by a scavenging collection.
DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations));
DEBUG_ONLY(ScavengableNMethods::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
}
Threads::oops_do
最终会执行到Thread::oops_do
void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
// Record JavaThread to GC thread
RememberProcessedThread rpt(this);
oops_do_no_frames(f, cf);
oops_do_frames(f, cf);
}
oops_do_frames
的定义
void JavaThread::oops_do_frames(OopClosure* f, CodeBlobClosure* cf) {
if (!has_last_Java_frame()) {
return;
}
// Finish any pending lazy GC activity for the frames
StackWatermarkSet::finish_processing(this, NULL /* context */, StackWatermarkKind::gc);
// Traverse the execution stack
for (StackFrameStream fst(this, true /* update */, false /* process_frames */); !fst.is_done(); fst.next()) {
fst.current()->oops_do(f, cf, fst.register_map()); // 这里会读取frame.oopMapSet
}
最终会执行
void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map,
DerivedPointerIterationMode derived_mode) const {
assert(_cb != NULL, "sanity check");
if (_cb->oop_maps() != NULL) {
OopMapSet::oops_do(this, reg_map, f, derived_mode);
...
}