hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
bool clear_all_softrefs) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
SharedHeap* sh = SharedHeap::heap();
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
---------------------------------------- -}
#ifdef ASSERT
if (sh->collector_policy()->should_clear_all_soft_refs()) {
assert(clear_all_softrefs, "Policy should have been checked earler");
}
#endif
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
// hook up weak ref data so it can be used during Mark-Sweep
assert(GenMarkSweep::ref_processor() == NULL, "no stomping");
assert(rp != NULL, "should be non-NULL");
{- -------------------------------------------
(1) rp 引数で渡された ReferenceProcessor を GenMarkSweep::_ref_processor フィールドに格納し,
ついでに ReferenceProcessor::setup_policy() を呼んで初期化もしておく.
---------------------------------------- -}
GenMarkSweep::_ref_processor = rp;
rp->setup_policy(clear_all_softrefs);
{- -------------------------------------------
(1) フレーム中の bcp (byte code pointer, バイトコードを指すポインタ) を格納している箇所については
GC によって methodOop が移動すると値が不正になってしまうので,
Threads::gc_prologue() を呼んで
フレーム中の bcp を bci (byte code index, そのバイトコードのメソッド先頭からのオフセット値) に変えておく.
(なお, CodeCache::gc_prologue()の方は, 単なる(assert) (See: CodeCache::gc_prologue()))
---------------------------------------- -}
// When collecting the permanent generation methodOops may be moving,
// so we either have to flush all bcp data or convert it into bci.
CodeCache::gc_prologue();
Threads::gc_prologue();
{- -------------------------------------------
(1)
---------------------------------------- -}
// Increment the invocation count for the permanent generation, since it is
// implicitly collected whenever we do a full mark sweep collection.
sh->perm_gen()->stat_record()->invocations++;
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
bool marked_for_unloading = false;
{- -------------------------------------------
(1) G1MarkSweep::allocate_stacks() を呼んで, mark フィールドの値を待避するための領域を確保しておく.
(See: PreservedMark)
---------------------------------------- -}
allocate_stacks();
{- -------------------------------------------
(1) BiasedLocking::preserve_marks() を呼んで,
mark フィールドが biased pattern になっているオブジェクトのうち
現在ロックを取得されているものについては,
その mark 値を待避しておく.
(この後の GC 処理では, 生きているオブジェクトに (生きているということを示すための) 印を付ける.
この印はオブジェクトの mark フィールドに書き込まれるが,
そのままだと元の mark フィールドの値は失われてしまうので,
元の mark をどこかに待避しておいて, GC 後に書き戻してやる必要がある.)
---------------------------------------- -}
// We should save the marks of the currently locked biased monitors.
// The marking doesn't preserve the marks of biased objects.
BiasedLocking::preserve_marks();
{- -------------------------------------------
(1) G1MarkSweep::mark_sweep_phase1() を呼んで,
全ての生きているオブジェクト(live object)にマークを付ける.
---------------------------------------- -}
mark_sweep_phase1(marked_for_unloading, clear_all_softrefs);
{- -------------------------------------------
(1) (verify)
---------------------------------------- -}
if (VerifyDuringGC) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
g1h->checkConcurrentMark();
}
{- -------------------------------------------
(1) G1MarkSweep::mark_sweep_phase2() を呼んで,
各 live object に対して, コンパクション後の新しいアドレスを forwarding pointer として埋め込む.
---------------------------------------- -}
mark_sweep_phase2();
{- -------------------------------------------
(1) #ifdef COMPILER2 の場合には, (これから GC を行うので) DerivedPointerTable の値をリセットしておく.
(See: DerivedPointerTable)
---------------------------------------- -}
// Don't add any more derived pointers during phase3
COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
{- -------------------------------------------
(1) G1MarkSweep::mark_sweep_phase3() を呼んで, 各 live object 内のポインタを新しいアドレスに修正する.
---------------------------------------- -}
mark_sweep_phase3();
{- -------------------------------------------
(1) G1MarkSweep::mark_sweep_phase4() を呼んで, 各 live object を新しいアドレスに移動させる.
---------------------------------------- -}
mark_sweep_phase4();
{- -------------------------------------------
(1) MarkSweep::restore_marks() を呼んで,
MarkSweep::preserve_mark() で待避していた mark 値を, 元のオブジェクトの mark フィールドに書き戻す.
(See: PreservedMark)
---------------------------------------- -}
GenMarkSweep::restore_marks();
{- -------------------------------------------
(1) BiasedLocking::restore_marks() を呼んで,
BiasedLocking::preserve_marks() で待避していた mark 値を
元のオブジェクトの mark フィールドに書き戻す.
---------------------------------------- -}
BiasedLocking::restore_marks();
{- -------------------------------------------
(1) GenMarkSweep::deallocate_stacks() を呼んで,
GenMarkSweep::allocate_stacks() で確保した領域を解放する.
(See: PreservedMark)
---------------------------------------- -}
GenMarkSweep::deallocate_stacks();
{- -------------------------------------------
(1) CardTableRS::invalidate() を呼んで, Perm 領域の Remembered Set を初期化しておく.
---------------------------------------- -}
// We must invalidate the perm-gen rs, so that it gets rebuilt.
GenRemSet* rs = sh->rem_set();
rs->invalidate(sh->perm_gen()->used_region(), true /*whole_heap*/);
{- -------------------------------------------
(1) (なんだかコメントアウトされているが... #TODO)
---------------------------------------- -}
// "free at last gc" is calculated from these.
// CHF: cheating for now!!!
// Universe::set_heap_capacity_at_last_gc(Universe::heap()->capacity());
// Universe::set_heap_used_at_last_gc(Universe::heap()->used());
{- -------------------------------------------
(1) フレーム中の bcp (byte code pointer, バイトコードを指すポインタ) を格納している箇所については
GC 前に Threads::gc_prologue() で
bcp から bci(byte code index, そのバイトコードのメソッド先頭からのオフセット値) へと値を変更していたので,
Threads::gc_epilogue() を呼んで元に戻しておく.
(ついでに, フレーム内の値について環境依存(プラットフォーム依存)な処理が必要であれば, それも行っている)
---------------------------------------- -}
Threads::gc_epilogue();
{- -------------------------------------------
(1) #TODO
---------------------------------------- -}
CodeCache::gc_epilogue();
{- -------------------------------------------
(1) JvmtiExport::gc_epilogue() を呼んで,
JvmtiBreakpointCache 内でキャッシュしているブレークポイントを指すポインタも更新しておく.
---------------------------------------- -}
JvmtiExport::gc_epilogue();
{- -------------------------------------------
(1)
---------------------------------------- -}
// refs processing: clean slate
GenMarkSweep::_ref_processor = NULL;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.