Top


定義場所(file name)

hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp

名前(function name)

  void work(int i) {

本体部(body)

  {- -------------------------------------------
  (1) もし, 同じタスクを2回以上取得した場合(??)には, することはないのでここでリターン.
        (なお _n_workers は G1CollectedHeap::evacuate_collection_set() 内で G1ParTask を生成する際に設定されている.
        値は (ParallelGCThreads > 0 ? workers()->total_workers() : 1).
        workers()->total_workers() の方は FlexibleWorkGang の生成時に指定される値で, ParallelGCThreads の値に設定されている.
        See: G1CollectedHeap::evacuate_collection_set(), SharedHeap::SharedHeap())
      ---------------------------------------- -}

        if (i >= _n_workers) return;  // no work needed this round

  {- -------------------------------------------
  (1) worker が処理を開始した時間(つまり現在時間)を G1CollectorPolicy に記録する.
      ---------------------------------------- -}

        double start_time_ms = os::elapsedTime() * 1000.0;
        _g1h->g1_policy()->record_gc_worker_start_time(i, start_time_ms);

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

        ResourceMark rm;
        HandleMark   hm;

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

        G1ParScanThreadState            pss(_g1h, i);
        G1ParScanHeapEvacClosure        scan_evac_cl(_g1h, &pss);
        G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss);
        G1ParScanPartialArrayClosure    partial_scan_cl(_g1h, &pss);

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

        pss.set_evac_closure(&scan_evac_cl);
        pss.set_evac_failure_closure(&evac_failure_cl);
        pss.set_partial_scan_closure(&partial_scan_cl);

  {- -------------------------------------------
  (1) (変数宣言など)
      (これらが実際に Copy 処理を行う Closure 達) ?? #TODO
      (G1ParScanHeapRSClosure の only_scan_heap_rs_cl と 
      G1ParScanAndMarkHeapRSClosure の scan_mark_heap_rs_cl は
      使われている箇所が見当たらないが... #TODO)
      ---------------------------------------- -}

        G1ParScanExtRootClosure         only_scan_root_cl(_g1h, &pss);
        G1ParScanPermClosure            only_scan_perm_cl(_g1h, &pss);
        G1ParScanHeapRSClosure          only_scan_heap_rs_cl(_g1h, &pss);
        G1ParPushHeapRSClosure          push_heap_rs_cl(_g1h, &pss);

        G1ParScanAndMarkExtRootClosure  scan_mark_root_cl(_g1h, &pss);
        G1ParScanAndMarkPermClosure     scan_mark_perm_cl(_g1h, &pss);
        G1ParScanAndMarkHeapRSClosure   scan_mark_heap_rs_cl(_g1h, &pss);

        OopsInHeapRegionClosure        *scan_root_cl;
        OopsInHeapRegionClosure        *scan_perm_cl;

  {- -------------------------------------------
  (1) 上記の Closure の中から実際に使用するものを選択.
      (Concurrent Marking の実施中かどうかで使用する Closure が異なる. 
      これは, 実施中であれば mark bit に記入する必要があるため)
      ---------------------------------------- -}

        if (_g1h->g1_policy()->during_initial_mark_pause()) {
          scan_root_cl = &scan_mark_root_cl;
          scan_perm_cl = &scan_mark_perm_cl;
        } else {
          scan_root_cl = &only_scan_root_cl;
          scan_perm_cl = &only_scan_perm_cl;
        }

  {- -------------------------------------------
  (1) まず, G1CollectedHeap::g1_process_strong_roots() を呼び出して root から参照されているオブジェクトを全て処理する.

      (なお, 処理の前後に G1ParScanThreadState::start_strong_roots() と
      G1ParScanThreadState::end_strong_roots() を入れ, 処理に掛かった時間を計測している)
      ---------------------------------------- -}

        pss.start_strong_roots();
        _g1h->g1_process_strong_roots(/* not collecting perm */ false,
                                      SharedHeap::SO_AllClasses,
                                      scan_root_cl,
                                      &push_heap_rs_cl,
                                      scan_perm_cl,
                                      i);
        pss.end_strong_roots();

  {- -------------------------------------------
  (1) 次に, G1ParEvacuateFollowersClosure::do_void() を呼び出して, 処理したオブジェクトから再帰的にたどれる範囲についても全て処理する.
        (なお, 処理の前後で os::elapsedTime() で時間を取得し, 
        また G1ParScanThreadState::term_time() 内に記録されている情報も使って
        コピー処理に掛かった時間(?)と...処理に掛かった時間を算出して
        G1CollectorPolicy に記録している.)
      ---------------------------------------- -}

        {
          double start = os::elapsedTime();
          G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
          evac.do_void();
          double elapsed_ms = (os::elapsedTime()-start)*1000.0;
          double term_ms = pss.term_time()*1000.0;
          _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms);
          _g1h->g1_policy()->record_termination(i, term_ms, pss.term_attempts());
        }

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

        _g1h->g1_policy()->record_thread_age_table(pss.age_table());
        _g1h->update_surviving_young_words(pss.surviving_young_words()+1);

  {- -------------------------------------------
  (1) HeapRegionRemSet::par_cleanup() を呼んで, 
      GC 処理中に PosParPRT::par_expand() で確保された PerRegionTable オブジェクトを
      全て開放しておく.
      (See: PerRegionTable)
      ---------------------------------------- -}

        // Clean up any par-expanded rem sets.
        HeapRegionRemSet::par_cleanup();

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

        if (ParallelGCVerbose) {
          MutexLocker x(stats_lock());
          pss.print_termination_stats(i);
        }

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

        assert(pss.refs()->is_empty(), "should be empty");

  {- -------------------------------------------
  (1) worker の処理が終了した時間(つまり現在時間)を G1CollectorPolicy に記録する.
      ---------------------------------------- -}

        double end_time_ms = os::elapsedTime() * 1000.0;
        _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms);
      }

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