hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
{- -------------------------------------------
(1) (この関数では, 生きているオブジェクトを再帰的に辿って印(mark)を付けていく)
---------------------------------------- -}
// Recursively traverse all live objects and mark them
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
EventMark m("1 mark object");
TraceTime tm("phase 1", PrintGCDetails && Verbose, true, gclog_or_tty);
trace(" 1");
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
{- -------------------------------------------
(1) まず, strong root から直接参照されているオブジェクトを marking stack に格納する.
---------------------------------------- -}
// General strong roots.
{
ParallelScavengeHeap::ParStrongRootsScope psrs;
Universe::oops_do(mark_and_push_closure());
ReferenceProcessor::oops_do(mark_and_push_closure());
JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles
CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
ObjectSynchronizer::oops_do(mark_and_push_closure());
FlatProfiler::oops_do(mark_and_push_closure());
Management::oops_do(mark_and_push_closure());
JvmtiExport::oops_do(mark_and_push_closure());
SystemDictionary::always_strong_oops_do(mark_and_push_closure());
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
//CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
}
{- -------------------------------------------
(1) 次に, MarkSweep::follow_stack() で
marking stack に溜まったポインタから辿りつけるオブジェクト全てに mark を付ける.
---------------------------------------- -}
// Flush marking stack.
follow_stack();
{- -------------------------------------------
(1) 最後に, ReferenceProcessor::process_discovered_references() を呼び出して,
marking 処理中に発見された参照オブジェクト(java.lang.ref オブジェクト) の処理を行う.
---------------------------------------- -}
// Process reference objects found during marking
{
ref_processor()->setup_policy(clear_all_softrefs);
ref_processor()->process_discovered_references(
is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL);
}
{- -------------------------------------------
(1) #TODO
---------------------------------------- -}
// Follow system dictionary roots and unload classes
bool purged_class = SystemDictionary::do_unloading(is_alive_closure());
// Follow code cache roots
CodeCache::do_unloading(is_alive_closure(), mark_and_push_closure(),
purged_class);
follow_stack(); // Flush marking stack
// Update subklass/sibling/implementor links of live klasses
follow_weak_klass_links();
assert(_marking_stack.is_empty(), "just drained");
// Visit memoized mdo's and clear unmarked weak refs
follow_mdo_weak_refs();
assert(_marking_stack.is_empty(), "just drained");
// Visit interned string tables and delete unmarked oops
StringTable::unlink(is_alive_closure());
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(_marking_stack.is_empty(), "stack should be empty by now");
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.