Top


定義場所(file name)

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

説明(description)

なお, コメントによると 「ReferenceProcessor::process_phase*() は 1 から 3 まで全てよく似ている. (どの関数も, DiscoveredList を辿って それぞれの参照オブジェクトに対して何らかの述語を適用し, 述語の判定結果に応じてリストからの除外と何らかの処理を行う, というだけ) なのでこれらは1つにまとめた方がいいかも」 とのこと.

// NOTE: process_phase*() are largely similar, and at a high level
// merely iterate over the extant list applying a predicate to
// each of its elements and possibly removing that element from the
// list and applying some further closures to that element.
// We should consider the possibility of replacing these
// process_phase*() methods by abstracting them into
// a single general iterator invocation that receives appropriate
// closures that accomplish this work.

// (SoftReferences 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.

名前(function name)

void
ReferenceProcessor::process_phase1(DiscoveredList&    refs_list,
                                   ReferencePolicy*   policy,
                                   BoolObjectClosure* is_alive,
                                   OopClosure*        keep_alive,
                                   VoidClosure*       complete_gc) {

本体部(body)

  {- -------------------------------------------
  (1) (assert)
      ---------------------------------------- -}

      assert(policy != NULL, "Must have a non-NULL policy");

  {- -------------------------------------------
  (1) (以下の while 文の中で, (DiscoveredListIterator を使って) 
       引数で渡された DiscoveredList を最初から最後まで辿って処理を行う)
      ---------------------------------------- -}

      DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
      // Decide which softly reachable refs should be kept alive.
      while (iter.has_next()) {

  {- -------------------------------------------
  (1) もし, soft reference の差し先が死んでいるものの
      ReferencePolicy による判定で消去すべきでないと判定された場合
      (= ReferencePolicy::should_clear_reference() が false の場合), 
      その soft reference はリストから除外する.
      (ついでに, DiscoveredListIterator::make_active() でその soft reference を Active 状態に戻し, 
       その差し先についても DiscoveredListIterator::make_referent_alive() で mark を付けて live 状態にする)

      (ついでに, 除外処理を行う際には(トレース出力)も出している)
      ---------------------------------------- -}

        iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
        bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
        if (referent_is_dead && !policy->should_clear_reference(iter.obj())) {
          if (TraceReferenceGC) {
            gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
                                   iter.obj(), iter.obj()->blueprint()->internal_name());
          }
          // Remove Reference object from list
          iter.remove();
          // Make the Reference object active again
          iter.make_active();
          // keep the referent around
          iter.make_referent_alive();
          iter.move_to_next();
        } else {
          iter.next();
        }
      }

  {- -------------------------------------------
  (1) 引数で渡されていた VoidClosure (以下の complete_gc) を用いて, 
      以上の処理で mark を付けられたオブジェクトから再帰的に辿れる範囲全てにも mark を付ける 
      (= 再帰的な到達範囲全てを live にする).
      ---------------------------------------- -}

      // Close the reachable set
      complete_gc->do_void();

  {- -------------------------------------------
  (1) (トレース出力)
      ---------------------------------------- -}

      NOT_PRODUCT(
        if (PrintGCDetails && TraceReferenceGC) {
          gclog_or_tty->print_cr(" Dropped %d dead Refs out of %d "
            "discovered Refs by policy  list " INTPTR_FORMAT,
            iter.removed(), iter.processed(), (address)refs_list.head());
        }
      )
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.