Top


定義場所(file name)

hotspot/src/share/vm/memory/referenceProcessor.cpp

名前(function name)

void ReferenceProcessor::process_discovered_references(
  BoolObjectClosure*           is_alive,
  OopClosure*                  keep_alive,
  VoidClosure*                 complete_gc,
  AbstractRefProcTaskExecutor* task_executor) {

本体部(body)

  {- -------------------------------------------
  (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.