G1CollectedHeap の Major GC 処理は, VM_G1CollectForAllocation::doit() を呼び出すことで行われる (See: here for details).
実際の Major GC 処理は, VM_G1CollectForAllocation::doit() から呼び出される G1MarkSweep::invoke_at_safepoint() の中に実装されている. この G1MarkSweep::invoke_at_safepoint() の処理は, 大きく分けると4つのフェーズからなる.
なお, ほとんどの処理は G1MarkSweep クラスで実装されている.
(基本的に Serial Old とほぼ同じなので, Serial Old を知ってたら見なくていい気もする...) (See: here for details)
-> VM_G1CollectForAllocation::doit() -> G1CollectedHeap::satisfy_failed_allocation() -> G1CollectedHeap::attempt_allocation_at_safepoint() -> G1CollectedHeap::humongous_obj_allocate() -> G1CollectedHeap::humongous_obj_allocate_find_first() -> G1CollectedHeap::expand_and_allocate() -> G1CollectedHeap::expand() -> VirtualSpace::expand_by() -> G1CollectedHeap::do_collection() -> G1MarkSweep::invoke_at_safepoint() -> (1) まず, 前準備をしておく -> -> ReferenceProcessor::setup_policy() -> -> G1MarkSweep::allocate_stacks() -> BiasedLocking::preserve_marks() (1) Phase 1: 全ての生きているオブジェクト(live object)にマークを付ける. -> G1MarkSweep::mark_sweep_phase1() -> (1) strong root から辿り着けるオブジェクト全てに mark を付ける. -> SharedHeap::process_strong_roots() (なお使用するクロージャーは (Perm領域用/非Perm領域用のどちらも) MarkSweep::FollowRootClosure) -> Universe::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> MarkSweep::follow_root() まだマークが付いていないオブジェクトであれば, 以下の処理を行う. -> MarkSweep::mark_object() でマークを付ける -> oopDesc::follow_contents() -> *Klass::oop_follow_contents() で再帰的にポインタを辿ってマークを付けていく. (#TODO クラス毎に少しずつ違うけど, 基本的には MarkSweep::mark_and_push() で辿るだけ??) -> ReferenceProcessor::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> ReferenceProcessor::weak_oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> JNIHandles::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> Threads::possibly_parallel_oops_do() または Threads::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> ObjectSynchronizer::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> FlatProfiler::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> Management::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> JvmtiExport::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> SystemDictionary::oops_do() または SystemDictionary::always_strong_oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> StringTable::oops_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) -> CodeCache::blobs_do() または CodeCache::scavenge_root_nmethods_do() -> (See: here for details) -> MarkSweep::FollowRootClosure::do_oop() -> (同上) (1) 以上の処理で見つかった参照オブジェクトを処理する. -> ReferenceProcessor::process_discovered_references() (なお使用するクロージャーは, MarkSweep::IsAliveClosure, MarkSweep::KeepAliveClosure, MarkSweep::FollowStackClosure. AbstractRefProcTaskExecutor は使用しない (NULL を渡す)) -> (See: here for details) (1) 最後に, #TODO -> (1) Phase 2: 各 live object に対して, コンパクション後の新しいアドレスを計算する. -> G1MarkSweep::mark_sweep_phase2() -> G1CollectedHeap::heap_region_iterate() (<= 先頭の HeapRegion (= コンパクション先アドレス) を取得) (なお使用するクロージャーは FindFirstRegionClosure) -> HeapRegionSeq::iterate() -> HeapRegionSeq::iterate_from() -> FindFirstRegionClosure::doHeapRegion() -> G1CollectedHeap::heap_region_iterate() (<= HeapRegion 内を処理) (なお使用するクロージャーは G1PrepareCompactClosure) -> (同上) -> G1PrepareCompactClosure::doHeapRegion() -> -> G1PrepareCompactClosure::update_sets() -> G1CollectedHeap::update_sets_after_freeing_regions() -> -> Generation::prepare_for_compaction() (<= Perm 領域内を処理) -> (1) Phase 3: 各 live object 内のポインタを新しいアドレスに修正する. -> G1MarkSweep::mark_sweep_phase3() -> SharedHeap::process_strong_roots() (なお使用するクロージャーは (Perm領域用/非Perm領域用のどちらも) MarkSweep::AdjustPointerClosure) -> (同上) -> MarkSweep::AdjustPointerClosure::do_oop() -> (See: here for details) -> ReferenceProcessor::weak_oops_do() (なお使用するクロージャーは MarkSweep::AdjustPointerClosure) -> G1CollectedHeap::g1_process_weak_roots() (なお使用するクロージャーは MarkSweep::AdjustPointerClosure) -> -> MarkSweep::adjust_marks() -> G1CollectedHeap::heap_region_iterate() (<= HeapRegion の処理) (なお使用するクロージャーは G1AdjustPointersClosure) -> (同上) -> G1AdjustPointersClosure::doHeapRegion() -> * Humongous オブジェクトの先頭にあたる場合: -> oopDesc::adjust_pointers() * Humongous ではない場合: -> CompactibleSpace::adjust_pointers() -> (See: here for details) -> CompactingPermGenGen::adjust_pointers() (<= Perm 領域の処理) -> (See: here for details) (1) Phase 4: 各 live object を新しいアドレスに移動させる. -> G1MarkSweep::mark_sweep_phase4() -> Generation::compact() (<= Perm 領域の処理) -> G1CollectedHeap::heap_region_iterate() (<= HeapRegion の処理) (なお使用するクロージャーは G1SpaceCompactClosure) -> (同上) -> G1SpaceCompactClosure::doHeapRegion() -> * Humongous オブジェクトの先頭にあたる場合: -> HeapRegion::reset_during_compaction() -> oopDesc::init_mark() * Humongous ではない場合: -> CompactibleSpace::compact() -> (See: here for details) (1) GC 処理の後片付けを行う -> MarkSweep::restore_marks() -> BiasedLocking::restore_marks() -> GenMarkSweep::deallocate_stacks() -> CardTableRS::invalidate() -> Threads::gc_epilogue() -> CodeCache::gc_epilogue() -> JvmtiExport::gc_epilogue() -> -> G1CollectedHeap::increment_full_collections_completed()
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
(#Under Construction)
See: here for details
(#Under Construction) See: here for details
See: here for details
(#Under Construction) See: here for details
See: here for details
(#Under Construction) See: here for details
(#Under Construction) See: here for details
(#Under Construction) See: here for details
処理の概要は以下のコメント参照. 引数で渡された OopClosure (引数名は roots) の do_oop() を全ての root に対して適用する関数.
なお, Perm 内を指しているポインタに付いては, 引数の collecting_perm_gen が false であれば見ない. この場合, 代わりに Perm 内のオブジェクトは全て live として, 引数で渡された OopsInGenClosure (引数名は perm_blk) を Perm 内の全ての (Perm 外への) 参照に対して適用する.
また, 処理対称にする root 種別は引数で選択することができる (引数名は so). 選択できる root 種別には以下のものがある. * SO_None * SO_AllClasses * SO_SystemClasses * SO_Strings * SO_CodeCache
((cite: hotspot/src/share/vm/memory/sharedHeap.hpp))
// Invoke the "do_oop" method the closure "roots" on all root locations.
// If "collecting_perm_gen" is false, then roots that may only contain
// references to permGen objects are not scanned; instead, in that case,
// the "perm_blk" closure is applied to all outgoing refs in the
// permanent generation. The "so" argument determines which of roots
// the closure is applied to:
// "SO_None" does none;
// "SO_AllClasses" applies the closure to all entries in the SystemDictionary;
// "SO_SystemClasses" to all the "system" classes and loaders;
// "SO_Strings" applies the closure to all entries in StringTable;
// "SO_CodeCache" applies the closure to all elements of the CodeCache.
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
(#Under Construction) See: here for details
See: here for details
(#Under Construction) 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
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.