hotspot/src/share/vm/memory/referenceProcessor.cpp
void ReferenceProcessor::process_discovered_references(
BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc,
AbstractRefProcTaskExecutor* task_executor) {
{- -------------------------------------------
(1) (verify)
---------------------------------------- -}
NOT_PRODUCT(verify_ok_to_handle_reflists());
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
{- -------------------------------------------
(1) ReferenceProcessor::disable_discovery() で, この ReferenceProcessor オブジェクトによる discover 処理を停止させる.
(disable にしている間は, ReferenceProcessor::discover_reference() が呼び出されても登録処理は行われない.
See: ReferenceProcessor::discover_reference())
---------------------------------------- -}
// Stop treating discovered references specially.
disable_discovery();
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
bool trace_time = PrintGCDetails && PrintReferenceGC;
{- -------------------------------------------
(1) まず Soft reference の処理を行う.
(ReferenceProcessor::process_discovered_reflist() を
ReferenceProcessor::_discoveredSoftRefs フィールドを引数として呼び出す)
(ついでにTraceTimeによる(トレース出力)も行っている)
---------------------------------------- -}
// Soft references
{
TraceTime tt("SoftReference", trace_time, false, gclog_or_tty);
process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
is_alive, keep_alive, complete_gc, task_executor);
}
{- -------------------------------------------
(1) 最後の GC 実行時間を表す java_lang_ref_SoftReference::clock() の値を現在時刻に更新しておく.
(See: LRUCurrentHeapPolicy, LRUMaxHeapPolicy)
---------------------------------------- -}
update_soft_ref_master_clock();
{- -------------------------------------------
(1) 次に Weak reference の処理を行う.
(ReferenceProcessor::process_discovered_reflist() を
ReferenceProcessor::_discoveredWeakRefs フィールドを引数として呼び出す)
(ついでにTraceTimeによる(トレース出力)も行っている)
---------------------------------------- -}
// Weak references
{
TraceTime tt("WeakReference", trace_time, false, gclog_or_tty);
process_discovered_reflist(_discoveredWeakRefs, NULL, true,
is_alive, keep_alive, complete_gc, task_executor);
}
{- -------------------------------------------
(1) 次に Final reference の処理を行う.
(ReferenceProcessor::process_discovered_reflist() を
ReferenceProcessor::_discoveredFinalRefs フィールドを引数として呼び出す)
(ついでにTraceTimeによる(トレース出力)も行っている)
---------------------------------------- -}
// Final references
{
TraceTime tt("FinalReference", trace_time, false, gclog_or_tty);
process_discovered_reflist(_discoveredFinalRefs, NULL, false,
is_alive, keep_alive, complete_gc, task_executor);
}
{- -------------------------------------------
(1) 次に Phantom reference の処理を行う.
(ReferenceProcessor::process_discovered_reflist() を
ReferenceProcessor::_discoveredPhantomRefs フィールドを引数として呼び出す)
(ついでにTraceTimeによる(トレース出力)も行っている)
---------------------------------------- -}
// Phantom references
{
TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty);
process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
is_alive, keep_alive, complete_gc, task_executor);
}
{- -------------------------------------------
(1) 最後に, ReferenceProcessor::process_phaseJNI() で
JNI の weak global reference の処理を行う.
(ついでにTraceTimeによる(トレース出力)も行っている)
(なお, 引数で渡された task_executor もここでお役ご免なので,
set_single_threaded_mode() メソッドを呼び出して後片付け(?)をしている.
<= といっても, このメソッドは ParNew 以外の場合は何もしないようだが...)
(コメントによると,
「"weak" という名前からすると, JNI の weak global reference も
java.lang.ref.WeakReference と同じタイミングで処理した方がいいような気もするが,
紛らわしいことに仕様ではそうなっていない」
とのこと.
なお, これを逆に利用すると,
「JNI の weak global reference を使うことで,
phantom reference が消されるのを防いだり, 死んだオブジェクトを復活させたりすることも可能」
とのこと.)
---------------------------------------- -}
// Weak global JNI references. It would make more sense (semantically) to
// traverse these simultaneously with the regular weak references above, but
// that is not how the JDK1.2 specification is. See #4126360. Native code can
// thus use JNI weak references to circumvent the phantom references and
// resurrect a "post-mortem" object.
{
TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty);
if (task_executor != NULL) {
task_executor->set_single_threaded_mode();
}
process_phaseJNI(is_alive, keep_alive, complete_gc);
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.