hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
void ConcurrentMark::checkpointRootsFinalWork() {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
ResourceMark rm;
HandleMark hm;
G1CollectedHeap* g1h = G1CollectedHeap::heap();
{- -------------------------------------------
(1) GC 処理の前に, CollectedHeap::ensure_parsability() を呼んで
各 TLAB に残っている未使用領域を埋め,
オブジェクトでひとつながりの状態(= GC で辿れる状態)にしておく.
---------------------------------------- -}
g1h->ensure_parsability(false);
{- -------------------------------------------
(1) CMRemarkTask::work() で Final marking pause 処理を行う.
(なお, G1CollectedHeap::use_parallel_gc_threads() が true の場合は,
WorkGang::run_task() 経由で呼び出す.
これにより, 処理がマルチスレッドで実行される)
(ついでに, 処理の実行前には ConcurrentMark::set_phase() も呼んで... #TODO)
---------------------------------------- -}
if (G1CollectedHeap::use_parallel_gc_threads()) {
G1CollectedHeap::StrongRootsScope srs(g1h);
// this is remark, so we'll use up all available threads
int active_workers = ParallelGCThreads;
set_phase(active_workers, false /* concurrent */);
CMRemarkTask remarkTask(this);
// We will start all available threads, even if we decide that the
// active_workers will be fewer. The extra ones will just bail out
// immediately.
int n_workers = g1h->workers()->total_workers();
g1h->set_par_threads(n_workers);
g1h->workers()->run_task(&remarkTask);
g1h->set_par_threads(0);
} else {
G1CollectedHeap::StrongRootsScope srs(g1h);
// this is remark, so we'll use up all available threads
int active_workers = 1;
set_phase(active_workers, false /* concurrent */);
CMRemarkTask remarkTask(this);
// We will start all available threads, even if we decide that the
// active_workers will be fewer. The extra ones will just bail out
// immediately.
remarkTask.work(0);
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant");
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
print_stats();
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
#if VERIFY_OBJS_PROCESSED
if (_scan_obj_cl.objs_processed != ThreadLocalObjQueue::objs_enqueued) {
gclog_or_tty->print_cr("Processed = %d, enqueued = %d.",
_scan_obj_cl.objs_processed,
ThreadLocalObjQueue::objs_enqueued);
guarantee(_scan_obj_cl.objs_processed ==
ThreadLocalObjQueue::objs_enqueued,
"Different number of objs processed and enqueued.");
}
#endif
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.