Top


定義場所(file name)

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

名前(function name)

G1CollectorPolicy::G1CollectorPolicy() :

本体部(body)

  {- -------------------------------------------
  (1) フィールドの初期化
      ---------------------------------------- -}

      _parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads()
        ? ParallelGCThreads : 1),


      _n_pauses(0),
      _recent_CH_strong_roots_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _recent_G1_strong_roots_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _recent_evac_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _recent_pause_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _recent_rs_sizes(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _all_pause_times_ms(new NumberSeq()),
      _stop_world_start(0.0),
      _all_stop_world_times_ms(new NumberSeq()),
      _all_yield_times_ms(new NumberSeq()),

      _all_mod_union_times_ms(new NumberSeq()),

      _summary(new Summary()),

    #ifndef PRODUCT
      _cur_clear_ct_time_ms(0.0),
      _min_clear_cc_time_ms(-1.0),
      _max_clear_cc_time_ms(-1.0),
      _cur_clear_cc_time_ms(0.0),
      _cum_clear_cc_time_ms(0.0),
      _num_cc_clears(0L),
    #endif

      _region_num_young(0),
      _region_num_tenured(0),
      _prev_region_num_young(0),
      _prev_region_num_tenured(0),

      _aux_num(10),
      _all_aux_times_ms(new NumberSeq[_aux_num]),
      _cur_aux_start_times_ms(new double[_aux_num]),
      _cur_aux_times_ms(new double[_aux_num]),
      _cur_aux_times_set(new bool[_aux_num]),

      _concurrent_mark_init_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),

      // <NEW PREDICTION>

      _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
      _prev_collection_pause_end_ms(0.0),
      _pending_card_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
      _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
      _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
      _fully_young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
      _partially_young_cards_per_entry_ratio_seq(
                                             new TruncatedSeq(TruncatedSeqLength)),
      _cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
      _partially_young_cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
      _cost_per_byte_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
      _cost_per_byte_ms_during_cm_seq(new TruncatedSeq(TruncatedSeqLength)),
      _constant_other_time_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
      _young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
      _non_young_other_cost_per_region_ms_seq(
                                             new TruncatedSeq(TruncatedSeqLength)),

      _pending_cards_seq(new TruncatedSeq(TruncatedSeqLength)),
      _scanned_cards_seq(new TruncatedSeq(TruncatedSeqLength)),
      _rs_lengths_seq(new TruncatedSeq(TruncatedSeqLength)),

      _pause_time_target_ms((double) MaxGCPauseMillis),

      // </NEW PREDICTION>

      _in_young_gc_mode(false),
      _full_young_gcs(true),
      _full_young_pause_num(0),
      _partial_young_pause_num(0),

      _during_marking(false),
      _in_marking_window(false),
      _in_marking_window_im(false),

      _known_garbage_ratio(0.0),
      _known_garbage_bytes(0),

      _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)),

       _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)),

      _recent_CS_bytes_used_before(new TruncatedSeq(NumPrevPausesForHeuristics)),
      _recent_CS_bytes_surviving(new TruncatedSeq(NumPrevPausesForHeuristics)),

      _recent_avg_pause_time_ratio(0.0),
      _num_markings(0),
      _n_marks(0),
      _n_pauses_at_mark_end(0),

      _all_full_gc_times_ms(new NumberSeq()),

      // G1PausesBtwnConcMark defaults to -1
      // so the hack is to do the cast  QQQ FIXME
      _pauses_btwn_concurrent_mark((size_t)G1PausesBtwnConcMark),
      _n_marks_since_last_pause(0),
      _initiate_conc_mark_if_possible(false),
      _during_initial_mark_pause(false),
      _should_revert_to_full_young_gcs(false),
      _last_full_young_gc(false),

      _prev_collection_pause_used_at_end_bytes(0),

      _collection_set(NULL),
      _collection_set_size(0),
      _collection_set_bytes_used_before(0),

      // Incremental CSet attributes
      _inc_cset_build_state(Inactive),
      _inc_cset_head(NULL),
      _inc_cset_tail(NULL),
      _inc_cset_size(0),
      _inc_cset_young_index(0),
      _inc_cset_bytes_used_before(0),
      _inc_cset_max_finger(NULL),
      _inc_cset_recorded_young_bytes(0),
      _inc_cset_recorded_rs_lengths(0),
      _inc_cset_predicted_elapsed_time_ms(0.0),
      _inc_cset_predicted_bytes_to_copy(0),

    #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
    #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
    #endif // _MSC_VER

      _short_lived_surv_rate_group(new SurvRateGroup(this, "Short Lived",
                                                     G1YoungSurvRateNumRegionsSummary)),
      _survivor_surv_rate_group(new SurvRateGroup(this, "Survivor",
                                                  G1YoungSurvRateNumRegionsSummary)),
      // add here any more surv rate groups
      _recorded_survivor_regions(0),
      _recorded_survivor_head(NULL),
      _recorded_survivor_tail(NULL),
      _survivors_age_table(true),

      _gc_overhead_perc(0.0)

    {

  {- -------------------------------------------
  (1) HeapRegion::setup_heap_region_size() 及び HeapRegionRemSet::setup_remset_size() を呼んで, 
      G1GC に関するコマンドラインオプションの値を調整しておく.
      ---------------------------------------- -}

      // Set up the region size and associated fields. Given that the
      // policy is created before the heap, we have to set this up here,
      // so it's done as soon as possible.
      HeapRegion::setup_heap_region_size(Arguments::min_heap_size());
      HeapRegionRemSet::setup_remset_size();

  {- -------------------------------------------
  (1) YoungPLABSize と OldPLABSize の値を確かめておく.
      (HeapRegion::GrainWords を超えているようなら, ここで異常終了させる)
      ---------------------------------------- -}

      // Verify PLAB sizes
      const uint region_size = HeapRegion::GrainWords;
      if (YoungPLABSize > region_size || OldPLABSize > region_size) {
        char buffer[128];
        jio_snprintf(buffer, sizeof(buffer), "%sPLABSize should be at most %u",
                     OldPLABSize > region_size ? "Old" : "Young", region_size);
        vm_exit_during_initialization(buffer);
      }

  {- -------------------------------------------
  (1) フィールドの初期化
      ---------------------------------------- -}

      _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
      _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;

      _par_last_gc_worker_start_times_ms = new double[_parallel_gc_threads];
      _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads];
      _par_last_mark_stack_scan_times_ms = new double[_parallel_gc_threads];

      _par_last_update_rs_times_ms = new double[_parallel_gc_threads];
      _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads];

      _par_last_scan_rs_times_ms = new double[_parallel_gc_threads];

      _par_last_obj_copy_times_ms = new double[_parallel_gc_threads];

      _par_last_termination_times_ms = new double[_parallel_gc_threads];
      _par_last_termination_attempts = new double[_parallel_gc_threads];
      _par_last_gc_worker_end_times_ms = new double[_parallel_gc_threads];
      _par_last_gc_worker_times_ms = new double[_parallel_gc_threads];

      // start conservatively
      _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis;

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

      // <NEW PREDICTION>

      int index;
      if (ParallelGCThreads == 0)
        index = 0;
      else if (ParallelGCThreads > 8)
        index = 7;
      else
        index = ParallelGCThreads - 1;

  {- -------------------------------------------
  (1) フィールドの初期化
      ---------------------------------------- -}

      _pending_card_diff_seq->add(0.0);
      _rs_length_diff_seq->add(rs_length_diff_defaults[index]);
      _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]);
      _fully_young_cards_per_entry_ratio_seq->add(
                                fully_young_cards_per_entry_ratio_defaults[index]);
      _cost_per_entry_ms_seq->add(cost_per_entry_ms_defaults[index]);
      _cost_per_byte_ms_seq->add(cost_per_byte_ms_defaults[index]);
      _constant_other_time_ms_seq->add(constant_other_time_ms_defaults[index]);
      _young_other_cost_per_region_ms_seq->add(
                                   young_other_cost_per_region_ms_defaults[index]);
      _non_young_other_cost_per_region_ms_seq->add(
                               non_young_other_cost_per_region_ms_defaults[index]);

      // </NEW PREDICTION>

  {- -------------------------------------------
  (1) (以下で, GC 停止時間の目標値(MaxGCPauseMillis) や 
       GC 実行間隔の目標値(GCPauseIntervalMillis)について
       値のチェックや計算を行う)

      (なおコメントによると, 
       目標値が指定されてなかった場合は, 最も柔軟性が高くなるように
       GCPauseIntervalMillis は MaxGCPauseMillis+1 に設定している
       (つまり MaxGCPauseMillis を GCPauseIntervalMillis を超えない範囲で最大限に大きくしている).
       この値が嫌なユーザーは明示的に GCPauseIntervalMillis を指定しないといけない, 
       とのこと)
      ---------------------------------------- -}

      // Below, we might need to calculate the pause time target based on
      // the pause interval. When we do so we are going to give G1 maximum
      // flexibility and allow it to do pauses when it needs to. So, we'll
      // arrange that the pause interval to be pause time target + 1 to
      // ensure that a) the pause time target is maximized with respect to
      // the pause interval and b) we maintain the invariant that pause
      // time target < pause interval. If the user does not want this
      // maximum flexibility, they will have to set the pause interval
      // explicitly.

    {- -------------------------------------------
  (1.1) まず MaxGCPauseMillis や GCPauseIntervalMillis の値を確かめておく.
        以下のどちらかが成り立てば, ここで異常終了させる.

        * MaxGCPauseMillis オプションが明示的に指定されているが, その値が 1 未満だった場合:
        * GCPauseIntervalMillis オプションが明示的に指定されているが, その値が 1 未満だった場合:
        ---------------------------------------- -}

      // First make sure that, if either parameter is set, its value is
      // reasonable.
      if (!FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
        if (MaxGCPauseMillis < 1) {
          vm_exit_during_initialization("MaxGCPauseMillis should be "
                                        "greater than 0");
        }
      }
      if (!FLAG_IS_DEFAULT(GCPauseIntervalMillis)) {
        if (GCPauseIntervalMillis < 1) {
          vm_exit_during_initialization("GCPauseIntervalMillis should be "
                                        "greater than 0");
        }
      }

    {- -------------------------------------------
  (1.1) 次に, MaxGCPauseMillis オプションが指定されていなかった場合は 200 に初期化する.

        (ただし, GCPauseIntervalMillis オプションが指定されていた場合は, 
        MaxGCPauseMillis 無しで GCPauseIntervalMillis だけ指定というのは許可していないので, 
        異常終了させる)
        ---------------------------------------- -}

      // Then, if the pause time target parameter was not set, set it to
      // the default value.
      if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
        if (FLAG_IS_DEFAULT(GCPauseIntervalMillis)) {
          // The default pause time target in G1 is 200ms
          FLAG_SET_DEFAULT(MaxGCPauseMillis, 200);
        } else {
          // We do not allow the pause interval to be set without the
          // pause time target
          vm_exit_during_initialization("GCPauseIntervalMillis cannot be set "
                                        "without setting MaxGCPauseMillis");
        }
      }

    {- -------------------------------------------
  (1.1) 次に, GCPauseIntervalMillis オプションが指定されてなかった場合には
        MaxGCPauseMillis + 1  に初期化しておく.
        ---------------------------------------- -}

      // Then, if the interval parameter was not set, set it according to
      // the pause time target (this will also deal with the case when the
      // pause time target is the default value).
      if (FLAG_IS_DEFAULT(GCPauseIntervalMillis)) {
        FLAG_SET_DEFAULT(GCPauseIntervalMillis, MaxGCPauseMillis + 1);
      }

    {- -------------------------------------------
  (1.1) 最後に, MaxGCPauseMillis と GCPauseIntervalMillis の値を確かめておく
        (MaxGCPauseMillis が GCPauseIntervalMillis 以上なら, ここで異常終了させる)
        ---------------------------------------- -}

      // Finally, make sure that the two parameters are consistent.
      if (MaxGCPauseMillis >= GCPauseIntervalMillis) {
        char buffer[256];
        jio_snprintf(buffer, 256,
                     "MaxGCPauseMillis (%u) should be less than "
                     "GCPauseIntervalMillis (%u)",
                     MaxGCPauseMillis, GCPauseIntervalMillis);
        vm_exit_during_initialization(buffer);
      }

  {- -------------------------------------------
  (1) フィールドの初期化
      ---------------------------------------- -}

      double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
      double time_slice  = (double) GCPauseIntervalMillis / 1000.0;
      _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
      _sigma = (double) G1ConfidencePercent / 100.0;

      // start conservatively (around 50ms is about right)
      _concurrent_mark_init_times_ms->add(0.05);
      _concurrent_mark_remark_times_ms->add(0.05);
      _concurrent_mark_cleanup_times_ms->add(0.20);
      _tenuring_threshold = MaxTenuringThreshold;

      // if G1FixedSurvivorSpaceSize is 0 which means the size is not
      // fixed, then _max_survivor_regions will be calculated at
      // calculate_young_list_target_length during initialization
      _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;

      assert(GCTimeRatio > 0,
             "we should have set it to a default value set_g1_gc_flags() "
             "if a user set it to 0");
      _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio));

  {- -------------------------------------------
  (1) G1CollectorPolicy::initialize_all() を呼んで, 
      残りの初期化を行う.
      ---------------------------------------- -}

      initialize_all();
    }

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