Top


定義場所(file name)

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

名前(function name)

void VM_G1IncCollectionPause::doit() {

本体部(body)

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

      G1CollectedHeap* g1h = G1CollectedHeap::heap();

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

      assert(!_should_initiate_conc_mark ||
      ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
       (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)),
             "only a GC locker or a System.gc() induced GC should start a cycle");

  {- -------------------------------------------
  (1) オブジェクトの確保が要求されている場合(= _word_size が 0 より大きい場合)には, 
      まず G1CollectedHeap::attempt_allocation_at_safepoint() でオブジェクトの確保を試みてみる.
      確保に成功してしまったら, ここでリターン.

      (ついでに _pause_succeeded を true にしているがこれは何だ?? #TODO)
      ---------------------------------------- -}

      if (_word_size > 0) {
        // An allocation has been requested. So, try to do that first.
        _result = g1h->attempt_allocation_at_safepoint(_word_size,
                                         false /* expect_null_cur_alloc_region */);
        if (_result != NULL) {
          // If we can successfully allocate before we actually do the
          // pause then we will consider this pause successful.
          _pause_succeeded = true;
          return;
        }
      }

  {- -------------------------------------------
  (1) 
      (See: GCCauseSetter)
      ---------------------------------------- -}

      GCCauseSetter x(g1h, _gc_cause);

  {- -------------------------------------------
  (1) コンストラクタ引数で明示的に「Full GC まで実行する」と指定されていた場合は, 
      Concurrent Marking を始めるためのフラグを立てておく.
      (ついでに, 現在の Full GC 実行回数も記録しておく)

      (なお, should_initiate_conc_mark コンストラクタ引数が true になるのは
       G1CollectedHeap::collect() 経由で呼び出される場合のみ.
       上記の assert も参照)
      ---------------------------------------- -}

      if (_should_initiate_conc_mark) {
        // It's safer to read full_collections_completed() here, given
        // that noone else will be updating it concurrently. Since we'll
        // only need it if we're initiating a marking cycle, no point in
        // setting it earlier.
        _full_collections_completed_before = g1h->full_collections_completed();

        // At this point we are supposed to start a concurrent cycle. We
        // will do so if one is not already in progress.
        bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle();
      }

  {- -------------------------------------------
  (1) G1CollectedHeap::do_collection_pause_at_safepoint() で GC を実行する.
      ---------------------------------------- -}

      _pause_succeeded =
        g1h->do_collection_pause_at_safepoint(_target_pause_time_ms);

  {- -------------------------------------------
  (1) もし GC が成功しており(?? #TODO), かつオブジェクトの確保が要求されている場合には, 
      最後に G1CollectedHeap::attempt_allocation_at_safepoint() でオブジェクトの確保を試みておく.
      ---------------------------------------- -}

      if (_pause_succeeded && _word_size > 0) {
        // An allocation had been requested.
        _result = g1h->attempt_allocation_at_safepoint(_word_size,
                                          true /* expect_null_cur_alloc_region */);
      } else {
        assert(_result == NULL, "invariant");
      }
    }

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