ConcurrentMarkThread は, HotSpot の初期化時に G1CollectedHeap::initialize() の中で生成される.
ConcurrentMarkThread の作成は os::create_thread() 及び os::start_thread() で行われる. このため, 生成された ConcurrentMarkThread スレッドは java_start() から実行が開始される (See: here for details).
java_start() から始まるスレッドの起動処理では最終的に Thread::run() が呼び出される (See: here for details). ConcurrentMarkThread は Thread::run() をオーバーライドしているので, 実際に呼び出されるのは ConcurrentMarkThread::run() になる. この ConcurrentMarkThread::run() の中で実際の Concurrent Marking 処理が行われる.
G1CollectedHeap::initialize() (See: here for details) -> ConcurrentMarkThread::ConcurrentMarkThread() -> ConcurrentGCThread::create_and_start() -> os::create_thread() -> (See: here for details) -> os::set_priority() -> os::start_thread() -> (See: here for details)
java_start() -> (See: here, here and here for details) -> ConcurrentMarkThread::run() -> (1) 初期化 -> ConcurrentGCThread::initialize_in_thread() (2) HotSpot の初期化が終わるまで待機する -> ConcurrentGCThread::wait_for_universe_init() (3) HotSpot が終了するまで, 以下の処理を無限ループ (1) 次回の concurrent mark cycle が始まるまで待機 (= G1CollectedHeap::doConcurrentMark() で起こされるまで待つ) -> ConcurrentMarkThread::sleepBeforeNextCycle() (2) Non-Generational G1GC の場合は Initial marking pause 処理を行う -> VMThread::execute() -> (略) (See: here for details) -> VM_CGC_Operation::doit_prologue() -> VM_CGC_Operation::doit() (<= コンストラクタ引数は CMCheckpointRootsInitialClosure) -> CMCheckpointRootsInitialClosure::do_void() -> ConcurrentMark::checkpointRootsInitial() -> SharedHeap::process_strong_roots() (なお使用するクロージャーは (Perm領域用/非Perm領域用のどちらも) CMMarkRootsClosure) -> (略) (See: ) -> CMMarkRootsClosure::do_oop() -> VM_CGC_Operation::doit_epilogue() (3) Concurrent marking 処理および Final marking pause 処理を行う. 失敗した場合は成功するまで繰り返す. (1) root から辿れる範囲に対して concurrent marking 処理を行う -> ConcurrentMark::markFromRoots() -> ConcurrentMark::set_phase() -> CMConcurrentMarkingTask::work() (<= マルチスレッドで行う場合は WorkGang::run_task() 経由で呼び出される) -> CMTask::do_marking_step() -> (1) SATB buffer 内のポインタを処理する -> CMTask::drain_satb_buffers() -> * multi-thread 用 -> SATBMarkQueueSet::par_apply_closure_to_completed_buffer() (使用するクロージャーは CMObjectClosure) -> SATBMarkQueueSet::apply_closure_to_completed_buffer_work() -> ObjPtrQueue::apply_closure_to_buffer() -> CMObjectClosure::do_object() -> CMTask::deal_with_reference() -> CMBitMap::parMark() -> CMTask::push() (<= finger より前のアドレスであれば呼び出す) -> GenericTaskQueue<E, N>::push() * single-thread 用 -> SATBMarkQueueSet::apply_closure_to_completed_buffer() (使用するクロージャーは CMObjectClosure) -> SATBMarkQueueSet::apply_closure_to_completed_buffer_work() -> (同上) -> CMTask::drain_local_queue() -> GenericTaskQueue<E, N>::pop_local() -> CMTask::scan_object() -> oopDesc::oop_iterate() -> (略) -> CMOopClosure::do_oop() -> CMOopClosure::do_oop_work() -> CMTask::deal_with_reference() -> (同上) -> CMTask::drain_global_stack() -> CMTask::get_entries_from_global_stack() -> CMTask::drain_local_queue() -> (同上) (2) Region stack 内のポインタを処理する -> CMTask::drain_region_stack() -> ConcurrentMark::region_stack_pop_lock_free() -> BitMap::iterate() (使用するクロージャーは CMBitMapClosure) -> CMBitMapClosure::do_bit() -> CMTask::scan_object() -> (同上) -> CMTask::drain_local_queue() -> (同上) -> CMTask::drain_global_stack() -> (同上) -> CMTask::drain_local_queue() -> (同上) -> CMTask::drain_global_stack() -> (同上) (3) 未処理の HeapRegion に対して, CMBitMapClosure での処理を行っていく. (以下の処理を先頭の HeapRegion から最後の HeapRegion まで行う. なお, 他の CMTask が既に処理した HeapRegion は処理しない) -> BitMap::iterate() (使用するクロージャーは CMBitMapClosure) -> CMBitMapClosure::do_bit() -> (同上) -> CMTask::drain_local_queue() -> CMTask::drain_global_stack() -> ConcurrentMark::claim_region() (3) SATB buffer 内のポインタを処理する -> CMTask::drain_satb_buffers() (3) -> CMTask::drain_local_queue() -> CMTask::drain_global_stack() (2) Final marking pause 処理を行う -> VMThread::execute() -> (略) (See: here for details) -> VM_CGC_Operation::doit_prologue() -> VM_CGC_Operation::doit() (<= コンストラクタ引数は CMCheckpointRootsInitialClosure) -> CMCheckpointRootsFinalClosure::do_void() -> ConcurrentMark::checkpointRootsFinal() -> (1) root から辿れる範囲に対して Final marking 処理を行う -> ConcurrentMark::checkpointRootsFinalWork() -> ConcurrentMark::set_phase() -> CMRemarkTask::work() (<= マルチスレッドで行う場合は WorkGang::run_task() 経由で呼び出される) -> CMTask::do_marking_step() -> (同上) (1) 以上の処理で見つかった参照オブジェクト(java.lang.ref オブジェクト)の処理を行う -> ConcurrentMark::weakRefsWork() -> ReferenceProcessor::process_discovered_references() (なお使用するクロージャーおよびAbstractRefProcTaskExecutorは, G1CMIsAliveClosure, G1CMKeepAliveClosure, G1CMDrainMarkingStackClosure, G1RefProcTaskExecutor) -> (See: here for details) なお, 並列処理する場合はこの中で G1RefProcTaskExecutor が使用される. G1RefProcTaskExecutor は, ReferenceProcessor::process_discovered_references() 内で RefProcPhase1Task, RefProcPhase2Task, RefProcPhase3Task に対して以下のように呼び出される -> G1RefProcTaskExecutor::execute() -> G1RefProcTaskProxy::work() (<= WorkGang::run_task() 経由で呼び出される) (なお使用するクロージャーは, G1CMIsAliveClosure, G1CMParKeepAliveAndDrainClosure, G1CMParDrainMarkingStackClosure) -> AbstractRefProcTaskExecutor::ProcessTask::work() -> (実際には各サブクラスがオーバーライドしたメソッドが呼び出される (See: RefProcPhase1Task::work(), RefProcPhase2Task::work(), RefProcPhase3Task::work())) (See: here for details) -> ReferenceProcessor::enqueue_discovered_references() (なお使用するAbstractRefProcTaskExecutorは, G1RefProcTaskExecutor) -> (See: here for details) -> StringTable::unlink() (なお使用するクロージャーは G1CMIsAliveClosure) -> SymbolTable::unlink() (1) 後片付け -> SATBMarkQueueSet::set_active_all_threads() -> VM_CGC_Operation::doit_epilogue() (4) Live Data Counting & Cleanup 処理を行う. -> VMThread::execute() -> (略) (See: here for details) -> VM_CGC_Operation::doit_prologue() -> VM_CGC_Operation::doit() (<= コンストラクタ引数は CMCleanUp) -> CMCleanUp::do_void() -> ConcurrentMark::cleanup() -> (1) Live Data Counting 処理を行う. -> G1ParFinalCountTask::work() (<= マルチスレッドで行う場合は WorkGang::run_task() 経由で呼び出される) -> * マルチスレッドで処理する場合 -> G1CollectedHeap::heap_region_par_iterate_chunked() (なお使用するクロージャーは CalcLiveObjectsClosure) -> CalcLiveObjectsClosure::doHeapRegion() * シングルスレッドで処理する場合 -> G1CollectedHeap::heap_region_iterate() (なお使用するクロージャーは CalcLiveObjectsClosure) -> HeapRegionSeq::iterate() -> HeapRegionSeq::iterate_from() -> CalcLiveObjectsClosure::doHeapRegion() (2) next marking bitmap と prev marking bitmap を入れ替える -> ConcurrentMark::swapMarkBitMaps() (3) Cleanup 処理を行う. -> G1ParNoteEndTask::work() (<= マルチスレッドで行う場合は WorkGang::run_task() 経由で呼び出される) -> * マルチスレッドで処理する場合 -> G1CollectedHeap::heap_region_par_iterate_chunked() (なお使用するクロージャーは G1NoteEndOfConcMarkClosure) -> G1NoteEndOfConcMarkClosure::doHeapRegion() -> HeapRegion::note_end_of_marking() -> G1CollectedHeap::free_region_if_empty() * シングルスレッドで処理する場合 -> G1CollectedHeap::heap_region_iterate() (なお使用するクロージャーは G1NoteEndOfConcMarkClosure) -> HeapRegionSeq::iterate() -> HeapRegionSeq::iterate_from() -> G1NoteEndOfConcMarkClosure::doHeapRegion() -> (同上) -> G1CollectedHeap::update_sets_after_freeing_regions() -> HeapRegionLinkedList::add_as_tail() -> HeapRegionRemSet::finish_cleanup_task() -> VM_CGC_Operation::doit_epilogue() (5) Cleanup 処理で空の HeapRegion が見つかっていた場合は処理を行う -> ConcurrentMark::completeCleanup() -> G1CollectedHeap::reset_free_regions_coming() (6) _nextMarkBitMap をクリアする -> ConcurrentMark::clearNextBitmap() (7) (Full GC の完了を待っているスレッドがいれば) 起床させておく (See: VM_G1IncCollectionPause::doit_epilogue()) -> G1CollectedHeap::increment_full_collections_completed() (7) (メインループが終わったので) 終了する -> ConcurrentGCThread::terminate()
なお, CMTask::do_marking_step() 部分の処理の流れは以下のようになる.
Evacuation Pause 時, もしくは "Initial Marking Pause" によって, root から辿れるものについては markbit が立っているはず.
ただし, Minor GC の処理途中とは異なり, mark されたものの一覧がスタック等に記録されているわけではないので, root から辿れるものがどれかを知りたければ markbit 全域をなめる必要がある.
そこで, 先頭の HeapRegion から開始して markbit を全て探索し, bit が立っている要素から再帰的に辿れる範囲を全て処理する, ということになる (この処理については, ConcurrentMark::_finger と CMTask::_finger によって, どこまで処理したかを記憶している).
ただし, concurrent に変更された要素については再調査が必要なので, SATB buffer や region stack 等も調査している.
See: here for details
(#Under Construction)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
(#Under Construction)
See: here for details
(#Under Construction)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
CMOopClosure::do_oop_work() を呼び出すだけ.
((cite: hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp))
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual void do_oop( oop* p) { do_oop_work(p); }
See: here for details
See: here for details
See: here for details
See: here for details
(#Under Construction)
See: here for details
See: here for details
(#Under Construction)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
(#Under Construction)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
(単なる getter method)
((cite: hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp))
bool expanded() { return _expanded; }
See: here for details
(#Under Construction)
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
SuspendibleThreadSet::should_yield() を呼び出すだけ.
((cite: hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp))
bool should_yield() { return _sts.should_yield(); }
((cite: hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.hpp))
// Returns "true" iff an suspension is in progress.
bool should_yield() { return _async_stop; }
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.