Top


定義場所(file name)

hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp

名前(function name)

void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {

本体部(body)

  {- -------------------------------------------
  (1) (この関数では, 生きているオブジェクトを再帰的に辿って印(mark)を付けていく)
      ---------------------------------------- -}

      // Recursively traverse all live objects and mark them

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

      EventMark m("1 mark object");
      TraceTime tm("phase 1", PrintGCDetails && Verbose, true, gclog_or_tty);
      trace(" 1");

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
      assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");

  {- -------------------------------------------
  (1) まず, strong root から直接参照されているオブジェクトを marking stack に格納する.
      ---------------------------------------- -}

      // General strong roots.
      {
        ParallelScavengeHeap::ParStrongRootsScope psrs;
        Universe::oops_do(mark_and_push_closure());
        ReferenceProcessor::oops_do(mark_and_push_closure());
        JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
        CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
        Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
        ObjectSynchronizer::oops_do(mark_and_push_closure());
        FlatProfiler::oops_do(mark_and_push_closure());
        Management::oops_do(mark_and_push_closure());
        JvmtiExport::oops_do(mark_and_push_closure());
        SystemDictionary::always_strong_oops_do(mark_and_push_closure());
        // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
        //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
      }

  {- -------------------------------------------
  (1) 次に, MarkSweep::follow_stack() で
      marking stack に溜まったポインタから辿りつけるオブジェクト全てに mark を付ける.
      ---------------------------------------- -}

      // Flush marking stack.
      follow_stack();

  {- -------------------------------------------
  (1) 最後に, ReferenceProcessor::process_discovered_references() を呼び出して, 
      marking 処理中に発見された参照オブジェクト(java.lang.ref オブジェクト) の処理を行う.
      ---------------------------------------- -}

      // Process reference objects found during marking
      {
        ref_processor()->setup_policy(clear_all_softrefs);
        ref_processor()->process_discovered_references(
          is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL);
      }

  {- -------------------------------------------
  (1) #TODO
      ---------------------------------------- -}

      // Follow system dictionary roots and unload classes
      bool purged_class = SystemDictionary::do_unloading(is_alive_closure());

      // Follow code cache roots
      CodeCache::do_unloading(is_alive_closure(), mark_and_push_closure(),
                              purged_class);
      follow_stack(); // Flush marking stack

      // Update subklass/sibling/implementor links of live klasses
      follow_weak_klass_links();
      assert(_marking_stack.is_empty(), "just drained");

      // Visit memoized mdo's and clear unmarked weak refs
      follow_mdo_weak_refs();
      assert(_marking_stack.is_empty(), "just drained");

      // Visit interned string tables and delete unmarked oops
      StringTable::unlink(is_alive_closure());
      // Clean up unreferenced symbols in symbol table.
      SymbolTable::unlink();

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

      assert(_marking_stack.is_empty(), "stack should be empty by now");
    }

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