これらは, Garbage Collection 処理用の補助クラス. より具体的に言うと, 参照オブジェクト (java.lang.ref オブジェクト) の GC 処理を行うクラス (See: here for details).
ReferenceProcessor クラスは, 参照オブジェクト(java.lang.ref.Reference オブジェクト)の GC 処理を行うクラス.
世代別 GC に対応するため, ヒープの一部分だけを対象とする機能も持っている (なお内部的には世代別だけに特化しないよう, "世代" ではなく "span" という用語を用いている).
各 ReferenceProcessor オブジェクトは, 指定された GC と対応づけられ, 指定の "span" 内にある java.lang.ref.Reference の処理を行う.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// ReferenceProcessor class encapsulates the per-"collector" processing
// of java.lang.Reference objects for GC. The interface is useful for supporting
// a generational abstraction, in particular when there are multiple
// generations that are being independently collected -- possibly
// concurrently and/or incrementally. Note, however, that the
// ReferenceProcessor class abstracts away from a generational setting
// by using only a heap interval (called "span" below), thus allowing
// its use in a straightforward manner in a general, non-generational
// setting.
//
// The basic idea is that each ReferenceProcessor object concerns
// itself with ("weak") reference processing in a specific "span"
// of the heap of interest to a specific collector. Currently,
// the span is a convex interval of the heap, but, efficiency
// apart, there seems to be no reason it couldn't be extended
// (with appropriate modifications) to any "non-convex interval".
java.lang.ref オブジェクトの処理は, ReferenceProcessor の以下のメソッドで行われる.
なお, この (A) や (B) の処理をマルチスレッドで行うための枠組みとして, AbstractRefProcTaskExecutor というクラスが用意されている. マルチスレッド化する場合は以下のようになる.
(A) や (B) のメソッドは引数として AbstractRefProcTaskExecutor オブジェクトを受け取れるようになっており, 呼び出された ReferenceProcessor オブジェクトの _processing_is_mt フィールドが true であれば, AbstractRefProcTaskExecutor::execute() による並列処理が行われる (逆に, 並列に行いたくないときには, この引数を NULL にして呼び出せばよい).
並列実行の際には, (A) や (B) の処理が AbstractRefProcTaskExecutor::ProcessTask クラスや AbstractRefProcTaskExecutor::EnqueueTask クラスのオブジェクトとして表現される. そして, AbstractRefProcTaskExecutor オブジェクトは「それらを受け取って並列に実行する」という役割を担う.
なお実際には AbstractRefProcTaskExecutor クラス自体は abstract class で, それぞれの GC アルゴリズム毎に具体的なサブクラスが存在している. (AbstractRefProcTaskExecutor::ProcessTask クラスや AbstractRefProcTaskExecutor::EnqueueTask クラスも abstract class であり, GC アルゴリズム毎に具体的なサブクラスを持つ)
java.lang.ref.Reference オブジェクトの処理を行うためのクラス (See: here for details).
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
class ReferenceProcessor : public CHeapObj {
このクラスの以下のメソッドが java.lang.ref.Reference オブジェクトの処理のエントリポイントになっている.
参照先が生きている参照オブジェクトをリストから除外する処理.
リストに残った参照オブジェクト(= 参照先が死んだので回収処理が必要な参照オブジェクト)を pending list に追加する処理.
See: here for details
ReferenceProcessor クラス用のユーティリティ・クラス(StackObjクラス).
ソースコード中のあるスコープの間だけ, ReferenceProcessor を無効にするためのクラス.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// A utility class to disable reference discovery in
// the scope which contains it, for given ReferenceProcessor.
class NoRefDiscovery: StackObj {
コンストラクタ引数で指定された ReferenceProcessor オブジェクトに対し, コンストラクタで disable_discovery() を呼び出し, デストラクタで元の状態に復元させている.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
NoRefDiscovery(ReferenceProcessor* rp) : _rp(rp) {
_was_discovering_refs = _rp->discovery_enabled();
if (_was_discovering_refs) {
_rp->disable_discovery();
}
}
~NoRefDiscovery() {
if (_was_discovering_refs) {
_rp->enable_discovery();
}
}
See: here for details
ReferenceProcessor クラス用のユーティリティ・クラス(StackObjクラス).
ソースコード中のあるスコープの間だけ, ReferenceProcessor の対象範囲を変更するためのクラス.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// A utility class to temporarily mutate the span of the
// given ReferenceProcessor in the scope that contains it.
class ReferenceProcessorSpanMutator: StackObj {
コンストラクタ引数で指定された ReferenceProcessor オブジェクトに対し, コンストラクタで set_span() を呼び出し, デストラクタで元の状態に復元させている.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
ReferenceProcessorSpanMutator(ReferenceProcessor* rp,
MemRegion span):
_rp(rp) {
_saved_span = _rp->span();
_rp->set_span(span);
}
~ReferenceProcessorSpanMutator() {
_rp->set_span(_saved_span);
}
See: here for details
ReferenceProcessor クラス用のユーティリティ・クラス(StackObjクラス).
ソースコード中のあるスコープの間だけ, ReferenceProcessor の処理をマルチスレッドで行うかどうかの設定を変更するためのクラス.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// A utility class to temporarily change the MT'ness of
// reference discovery for the given ReferenceProcessor
// in the scope that contains it.
class ReferenceProcessorMTDiscoveryMutator: StackObj {
コンストラクタ引数で指定された ReferenceProcessor オブジェクトに対し, コンストラクタで set_mt_discovery() を呼び出し, デストラクタで元の状態に復元させている.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
ReferenceProcessorMTDiscoveryMutator(ReferenceProcessor* rp,
bool mt):
_rp(rp) {
_saved_mt = _rp->discovery_is_mt();
_rp->set_mt_discovery(mt);
}
~ReferenceProcessorMTDiscoveryMutator() {
_rp->set_mt_discovery(_saved_mt);
}
See: here for details
ReferenceProcessor クラス用のユーティリティ・クラス(StackObjクラス).
ソースコード中のあるスコープの間だけ, ReferenceProcessor の _is_alive_non_header フィールドを変更するためのクラス.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// A utility class to temporarily change the disposition
// of the "is_alive_non_header" closure field of the
// given ReferenceProcessor in the scope that contains it.
class ReferenceProcessorIsAliveMutator: StackObj {
なお _is_alive_non_header フィールドとは, mark フィールドに情報を書き込まない GC アルゴリズムと併用する場合に, オブジェクトに GC が到達するかどうかを知るための Closure を入れておくフィールド (現在は CMS と併用する場合にしか使われない).
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// For collectors that do not keep GC marking information
// in the object header, this field holds a closure that
// helps the reference processor determine the reachability
// of an oop (the field is currently initialized to NULL for
// all collectors but the CMS collector).
BoolObjectClosure* _is_alive_non_header;
コンストラクタ引数で指定された ReferenceProcessor オブジェクトに対し, コンストラクタで set_is_alive_non_header() を呼び出し, デストラクタで元の状態に復元させている.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
ReferenceProcessorIsAliveMutator(ReferenceProcessor* rp,
BoolObjectClosure* cl):
_rp(rp) {
_saved_cl = _rp->is_alive_non_header();
_rp->set_is_alive_non_header(cl);
}
~ReferenceProcessorIsAliveMutator() {
_rp->set_is_alive_non_header(_saved_cl);
}
See: here for details
ReferenceProcessor クラス用のユーティリティ・クラス(StackObjクラス).
ソースコード中のあるスコープの間だけ, ReferenceProcessor の discovery_is_atomic フィールドを変更するためのクラス.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// A utility class to temporarily change the disposition
// of the "discovery_is_atomic" field of the
// given ReferenceProcessor in the scope that contains it.
class ReferenceProcessorAtomicMutator: StackObj {
コンストラクタ引数で指定された ReferenceProcessor オブジェクトに対し, コンストラクタで set_atomic_discovery() を呼び出し, デストラクタで元の状態に復元させている.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
ReferenceProcessorAtomicMutator(ReferenceProcessor* rp,
bool atomic):
_rp(rp) {
_saved_atomic_discovery = _rp->discovery_is_atomic();
_rp->set_atomic_discovery(atomic);
}
~ReferenceProcessorAtomicMutator() {
_rp->set_atomic_discovery(_saved_atomic_discovery);
}
See: here for details
ReferenceProcessor クラス用のユーティリティ・クラス(StackObjクラス).
ソースコード中のあるスコープの間だけ, ReferenceProcessor の _processing_is_mt フィールドを変更するためのクラス.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// A utility class to temporarily change the MT processing
// disposition of the given ReferenceProcessor instance
// in the scope that contains it.
class ReferenceProcessorMTProcMutator: StackObj {
コンストラクタ引数で指定された ReferenceProcessor オブジェクトに対し, コンストラクタで set_mt_processing() を呼び出し, デストラクタで元の状態に復元させている.
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
ReferenceProcessorMTProcMutator(ReferenceProcessor* rp,
bool mt):
_rp(rp) {
_saved_mt = _rp->processing_is_mt();
_rp->set_mt_processing(mt);
}
~ReferenceProcessorMTProcMutator() {
_rp->set_mt_processing(_saved_mt);
}
See: here for details
ReferenceProcessor の処理をマルチスレッド化するクラス (の基底クラス).
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// This class is an interface used to implement task execution for the
// reference processing.
class AbstractRefProcTaskExecutor {
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
See: here for details
ReferenceProcessor::process_discovered_references() の処理をマルチスレッド化するクラス (の基底クラス).
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// Abstract reference processing task to execute.
class AbstractRefProcTaskExecutor::ProcessTask {
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
See: here for details
ReferenceProcessor::enqueue_discovered_references() の処理をマルチスレッド化するクラス (の基底クラス).
((cite: hotspot/src/share/vm/memory/referenceProcessor.hpp))
// Abstract reference processing task to execute.
class AbstractRefProcTaskExecutor::EnqueueTask {
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
See: here for details
ReferenceProcessor クラス内で使用される補助クラス.
ReferenceProcessor::discover_reference() で見つかった結果を格納しておくためのリスト (See: here for details).
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
// List of discovered references.
class DiscoveredList {
See: here for details
デバッグ用(開発時用)のクラス (#ifndef PRODUCT 時にしか定義されない).
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
#ifndef PRODUCT
ReferenceProcessor::count_jni_refs() 内で使用される補助クラス (というか, ReferenceProcessor::count_jni_refs() 内で定義されているので関数外からは見えもしないが.... なお ReferenceProcessor::count_jni_refs() 自体も #ifndef PRODUCT 時にしか定義されない関数で, JNI Weak Global Handle の数を数えてリターンするというもの)
JNI の Weak Global Handle を辿る処理で使用される Closure.
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
class AlwaysAliveClosure: public BoolObjectClosure {
同名のクラスが hotspot/src/share/vm/runtime/jniHandles.cpp にいたりするが (そして処理もそっくりだが), 特に関係は無い模様.
See: here for details
デバッグ用(開発時用)のクラス (#ifndef PRODUCT 時にしか定義されない).
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
#ifndef PRODUCT
ReferenceProcessor::count_jni_refs() 内で使用される補助クラス (というか, ReferenceProcessor::count_jni_refs() 内で定義されているので関数外からは見えもしないが.... なお ReferenceProcessor::count_jni_refs() 自体も #ifndef PRODUCT 時にしか定義されない関数で, JNI Weak Global Handle の数を数えてリターンするというもの)
JNI の Weak Global Handle を数える処理で使用される Closure.
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
class CountHandleClosure: public OopClosure {
同名のクラスが hotspot/src/share/vm/runtime/jniHandles.cpp にいたりするが (そして処理もそっくりだが), 特に関係は無い模様.
See: here for details
ReferenceProcessor::enqueue_discovered_references() 内で使用される補助クラス (より正確には, そこから呼び出される ReferenceProcessor::enqueue_discovered_reflists() 内で使用される補助クラス).
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
// Parallel enqueue task
class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
AbstractRefProcTaskExecutor::EnqueueTask のサブクラス.
このオブジェクトが AbstractRefProcTaskExecutor に渡されることで ReferenceProcessor::enqueue_discovered_references() の処理がマルチスレッド化される.
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
// Enqueue references that are not made active again
void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
AbstractRefProcTaskExecutor* task_executor) {
if (_processing_is_mt && task_executor != NULL) {
// Parallel code
RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
pending_list_addr, sentinel_ref(), _max_num_q);
task_executor->execute(tsk);
} else {
See: here for details
DiscoveredList を辿るためのイテレータクラス.
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
// Iterator for the list of discovered references.
class DiscoveredListIterator {
See: here for details
ReferenceProcessor::process_discovered_references() 内で使用される補助クラス (より正確には, そこから呼び出される ReferenceProcessor::process_discovered_reflist() 内で使用される補助クラス).
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
class RefProcPhase1Task: public AbstractRefProcTaskExecutor::ProcessTask {
AbstractRefProcTaskExecutor::ProcessTask のサブクラス.
このオブジェクトが AbstractRefProcTaskExecutor に渡されることで ReferenceProcessor::process_discovered_reflist() の Phase 1 の処理がマルチスレッド化される.
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
// Phase 1 (soft refs only):
// . Traverse the list and remove any SoftReferences whose
// referents are not alive, but that should be kept alive for
// policy reasons. Keep alive the transitive closure of all
// such referents.
if (policy != NULL) {
if (mt_processing) {
RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);
task_executor->execute(phase1);
} else {
See: here for details
ReferenceProcessor::process_discovered_references() 内で使用される補助クラス (より正確には, そこから呼び出される ReferenceProcessor::process_discovered_reflist() 内で使用される補助クラス).
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
class RefProcPhase2Task: public AbstractRefProcTaskExecutor::ProcessTask {
AbstractRefProcTaskExecutor::ProcessTask のサブクラス.
このオブジェクトが AbstractRefProcTaskExecutor に渡されることで ReferenceProcessor::process_discovered_reflist() の Phase 2 の処理がマルチスレッド化される.
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
// Phase 2:
// . Traverse the list and remove any refs whose referents are alive.
if (mt_processing) {
RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);
task_executor->execute(phase2);
} else {
See: here for details
ReferenceProcessor::process_discovered_references() 内で使用される補助クラス (より正確には, そこから呼び出される ReferenceProcessor::process_discovered_reflist() 内で使用される補助クラス).
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
class RefProcPhase3Task: public AbstractRefProcTaskExecutor::ProcessTask {
AbstractRefProcTaskExecutor::ProcessTask のサブクラス.
このオブジェクトが AbstractRefProcTaskExecutor に渡されることで ReferenceProcessor::process_discovered_reflist() の Phase 3 の処理がマルチスレッド化される.
((cite: hotspot/src/share/vm/memory/referenceProcessor.cpp))
// Phase 3:
// . Traverse the list and process referents as appropriate.
if (mt_processing) {
RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
task_executor->execute(phase3);
} else {
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.