これらは, Java ヒープ領域を管理するためのクラス (See: here for details).
Java ヒープ領域を管理するクラスは使用する GC アルゴリズムによって異なるが, これらのクラスは GC アルゴリズムが ParallelScavenge ではない場合に使用されるクラス (の基底クラス). (See: GenCollectedHeap, G1CollectedHeap)
CollectedHeap クラスのサブクラスの1つ (= Java ヒープ領域の管理を担当するクラス)
このクラスは, GC アルゴリズムが ParallelScavenge 以外の場合に使用される CollectedHeap クラス (の基底クラス) (つまり GC アルゴリズムが Serial Old, CMS, または G1GC の場合用).
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
((cite: hotspot/src/share/vm/memory/sharedHeap.hpp))
// A "SharedHeap" is an implementation of a java heap for HotSpot. This
// is an abstract class: there may be many different kinds of heaps. This
// class defines the functions that a heap must implement, and contains
// infrastructure common to all heaps.
((cite: hotspot/src/share/vm/memory/sharedHeap.hpp))
class SharedHeap : public CollectedHeap {
See: here for details
SharedHeap 用の MarkingCodeBlobClosure::MarkScope クラス (See: MarkingCodeBlobClosure::MarkScope).
MarkingCodeBlobClosure::MarkScope としての役割の他に, SharedHeap::_strong_roots_parity の値をフリップさせるという役割を持っている.
((cite: hotspot/src/share/vm/memory/sharedHeap.hpp))
// Call these in sequential code around process_strong_roots.
// strong_roots_prologue calls change_strong_roots_parity, if
// parallel tasks are enabled.
class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
(なお SharedHeap::_strong_roots_parity は, マルチスレッドで処理する GC の場合に SharedHeap::process_strong_roots() 内の並列化しやすい処理 (threads の処理等) を簡単に並列化するための枠組み (備考参照))
((cite: hotspot/src/share/vm/memory/sharedHeap.hpp))
// Some collectors will perform "process_strong_roots" in parallel.
// Such a call will involve claiming some fine-grained tasks, such as
// scanning of threads. To make this process simpler, we provide the
// "strong_roots_parity()" method. Collectors that start parallel tasks
// whose threads invoke "process_strong_roots" must
// call "change_strong_roots_parity" in sequential code starting such a
// task. (This also means that a parallel thread may only call
// process_strong_roots once.)
//
// For calls to process_strong_roots by sequential code, the parity is
// updated automatically.
//
// The idea is that objects representing fine-grained tasks, such as
// threads, will contain a "parity" field. A task will is claimed in the
// current "process_strong_roots" call only if its parity field is the
// same as the "strong_roots_parity"; task claiming is accomplished by
// updating the parity field to the strong_roots_parity with a CAS.
//
// If the client meats this spec, then strong_roots_parity() will have
// the following properties:
// a) to return a different value than was returned before the last
// call to change_strong_roots_parity, and
// c) to never return a distinguished value (zero) with which such
// task-claiming variables may be initialized, to indicate "never
// claimed".
コンストラクタで SharedHeap::change_strong_roots_parity() を呼び出して SharedHeap::_strong_roots_parity の値を変更している (なお, デストラクタでは特に何もしていない).
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* outer, bool activate)
: MarkScope(activate)
{
if (_active) {
outer->change_strong_roots_parity();
}
}
SharedHeap::StrongRootsScope::~StrongRootsScope() {
// nothing particular
}
コンストラクタから呼び出された SharedHeap::change_strong_roots_parity() では, SharedHeap::strong_roots_parity の値を 1~2 の間でフリップさせている (正確には初期値が 0 なので 0 -> 1 -> 2 -> 1 -> 2 -> 1 -> ... だが, 最初の 0 は SharedHeap::strongroots_parity() の返値としては見えないので実質 1~2 だけ).
そして, この SharedHeap::_strong_roots_parity の値は, 現状では以下の 2カ所で使われている.
この2箇所での使われ方は以下の通り. これにより JavaThread という単位で GC 処理が並列化される.
以下の処理をマルチスレッドで行う.
全ての JavaThread に対して Thread::claim_oops_do() を呼び出す.
この中では, Atomic::cmpxchg() により, JavaThread::oops_do_parity フィールドを 1つ前の _strong_roots_parity の値から現在の _strongroots_parity の値に書き換える処理が試みられる.
書き換えが成功した GC スレッドがその JavaThread の処理を担当する.
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
SharedHeap::SharedHeap(CollectorPolicy* policy_) :
...
_strong_roots_parity(0),
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
デバッグ用(開発時用)のクラス.
処理対象の oop* が Perm 領域内にあることを検証する.
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
class AssertIsPermClosure: public OopClosure {
assert_is_perm_closure という大域変数に(のみ)格納されている.
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
static AssertIsPermClosure assert_is_perm_closure;
SharedHeap::process_strong_roots() 内で, StringTable 内の文字列が Perm 領域内に入っていることを確かめるために使われている.
(なおこの処理は, NOT_PRODUCT 時で, かつ develop オプションである JavaObjectsInPerm が指定されている場合でないと実行されない)
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
void SharedHeap::process_strong_roots(bool activate_scope,
bool collecting_perm_gen,
ScanningOption so,
OopClosure* roots,
CodeBlobClosure* code_roots,
OopsInGenClosure* perm_blk) {
...
if (JavaObjectsInPerm) {
// Verify the string table contents are in the perm gen
NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
See: here for details
デバッグ用(開発時用)のクラス (#ifdef ASSERT 時にしか定義されない).
処理対象の oop* が Minor GC の処理対象範囲内にないことを検証する.
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
#ifdef ASSERT
class AssertNonScavengableClosure: public OopClosure {
assert_is_non_scavengable_closure という大域変数に(のみ)格納されている.
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
static AssertNonScavengableClosure assert_is_non_scavengable_closure;
SharedHeap::process_strong_roots() 内で, CodeCache 内の CodeBlob には New 領域内を指すポインタを持っているものは存在しない, ということを確かめるために使われている.
(なおこの処理は, DEBUG_ONLY 時にしか実行されない)
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
void SharedHeap::process_strong_roots(bool activate_scope,
bool collecting_perm_gen,
ScanningOption so,
OopClosure* roots,
CodeBlobClosure* code_roots,
OopsInGenClosure* perm_blk) {
...
// Verify that the code cache contents are not subject to
// movement by a scavenging collection.
DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, /*do_marking=*/ false));
DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
See: here for details
SharedHeap::process_weak_roots() 内で使用される補助クラス (つまり, JNI の Weak Global Handle を辿る処理で使用される Closure クラス).
名前の通り, どんな場合でも常に true を返す BoolObjectClosure.
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
class AlwaysTrueClosure: public BoolObjectClosure {
always_true という大域変数に(のみ)格納されている.
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
static AlwaysTrueClosure always_true;
SharedHeap::process_weak_roots() 内で(のみ)使用されている.
(なお, phase1 の中で ReferenceProcessor::process_discovered_references() が呼び出された段階で, 死んでいる Weak Global Reference については NULL になっている. このため, AlwaysTrueClosure のような常に true を返すだけの Closure でも, 生きている Weak Global Reference だけを全て辿ることができる.)
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
void SharedHeap::process_weak_roots(OopClosure* root_closure,
CodeBlobClosure* code_roots,
OopClosure* non_root_closure) {
// Global (weak) JNI handles
JNIHandles::weak_oops_do(&always_true, root_closure);
See: here for details
SharedHeap::process_weak_roots() 内で使用される補助クラス (つまり, JNI の Weak Global Handle を辿る処理で使用される Closure クラス).
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
class SkipAdjustingSharedStrings: public OopClosure {
((cite: hotspot/src/share/vm/memory/sharedHeap.cpp))
void SharedHeap::process_weak_roots(OopClosure* root_closure,
CodeBlobClosure* code_roots,
OopClosure* non_root_closure) {
...
if (UseSharedSpaces && !DumpSharedSpaces) {
SkipAdjustingSharedStrings skip_closure(root_closure);
StringTable::oops_do(&skip_closure);
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.