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

changeset 3358
1cbe7978b021
parent 3357
441e946dc1af
child 3416
2ace1c4ee8da
     1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Dec 14 13:34:57 2011 -0800
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Dec 21 22:13:31 2011 +0100
     1.3 @@ -136,7 +136,6 @@
     1.4    _stop_world_start(0.0),
     1.5    _all_stop_world_times_ms(new NumberSeq()),
     1.6    _all_yield_times_ms(new NumberSeq()),
     1.7 -  _using_new_ratio_calculations(false),
     1.8  
     1.9    _summary(new Summary()),
    1.10  
    1.11 @@ -409,11 +408,7 @@
    1.12  
    1.13    initialize_all();
    1.14    _collectionSetChooser = new CollectionSetChooser();
    1.15 -}
    1.16 -
    1.17 -// Increment "i", mod "len"
    1.18 -static void inc_mod(int& i, int len) {
    1.19 -  i++; if (i == len) i = 0;
    1.20 +  _young_gen_sizer = new G1YoungGenSizer(); // Must be after call to initialize_flags
    1.21  }
    1.22  
    1.23  void G1CollectorPolicy::initialize_flags() {
    1.24 @@ -425,71 +420,88 @@
    1.25    CollectorPolicy::initialize_flags();
    1.26  }
    1.27  
    1.28 -// The easiest way to deal with the parsing of the NewSize /
    1.29 -// MaxNewSize / etc. parameteres is to re-use the code in the
    1.30 -// TwoGenerationCollectorPolicy class. This is similar to what
    1.31 -// ParallelScavenge does with its GenerationSizer class (see
    1.32 -// ParallelScavengeHeap::initialize()). We might change this in the
    1.33 -// future, but it's a good start.
    1.34 -class G1YoungGenSizer : public TwoGenerationCollectorPolicy {
    1.35 -private:
    1.36 -  size_t size_to_region_num(size_t byte_size) {
    1.37 -    return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
    1.38 -  }
    1.39 -
    1.40 -public:
    1.41 -  G1YoungGenSizer() {
    1.42 -    initialize_flags();
    1.43 -    initialize_size_info();
    1.44 -  }
    1.45 -  size_t min_young_region_num() {
    1.46 -    return size_to_region_num(_min_gen0_size);
    1.47 -  }
    1.48 -  size_t initial_young_region_num() {
    1.49 -    return size_to_region_num(_initial_gen0_size);
    1.50 -  }
    1.51 -  size_t max_young_region_num() {
    1.52 -    return size_to_region_num(_max_gen0_size);
    1.53 -  }
    1.54 -};
    1.55 -
    1.56 -void G1CollectorPolicy::update_young_list_size_using_newratio(size_t number_of_heap_regions) {
    1.57 -  assert(number_of_heap_regions > 0, "Heap must be initialized");
    1.58 -  size_t young_size = number_of_heap_regions / (NewRatio + 1);
    1.59 -  _min_desired_young_length = young_size;
    1.60 -  _max_desired_young_length = young_size;
    1.61 -}
    1.62 -
    1.63 -void G1CollectorPolicy::init() {
    1.64 -  // Set aside an initial future to_space.
    1.65 -  _g1 = G1CollectedHeap::heap();
    1.66 -
    1.67 -  assert(Heap_lock->owned_by_self(), "Locking discipline.");
    1.68 -
    1.69 -  initialize_gc_policy_counters();
    1.70 -
    1.71 -  G1YoungGenSizer sizer;
    1.72 -  _min_desired_young_length = sizer.min_young_region_num();
    1.73 -  _max_desired_young_length = sizer.max_young_region_num();
    1.74 +G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true) {
    1.75 +  assert(G1DefaultMinNewGenPercent <= G1DefaultMaxNewGenPercent, "Min larger than max");
    1.76 +  assert(G1DefaultMinNewGenPercent > 0 && G1DefaultMinNewGenPercent < 100, "Min out of bounds");
    1.77 +  assert(G1DefaultMaxNewGenPercent > 0 && G1DefaultMaxNewGenPercent < 100, "Max out of bounds");
    1.78  
    1.79    if (FLAG_IS_CMDLINE(NewRatio)) {
    1.80      if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
    1.81        warning("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
    1.82      } else {
    1.83 -      // Treat NewRatio as a fixed size that is only recalculated when the heap size changes
    1.84 -      update_young_list_size_using_newratio(_g1->n_regions());
    1.85 -      _using_new_ratio_calculations = true;
    1.86 +      _sizer_kind = SizerNewRatio;
    1.87 +      _adaptive_size = false;
    1.88 +      return;
    1.89      }
    1.90    }
    1.91  
    1.92 +  if (FLAG_IS_CMDLINE(NewSize)) {
    1.93 +     _min_desired_young_length = MAX2((size_t) 1, NewSize / HeapRegion::GrainBytes);
    1.94 +    if (FLAG_IS_CMDLINE(MaxNewSize)) {
    1.95 +      _max_desired_young_length = MAX2((size_t) 1, MaxNewSize / HeapRegion::GrainBytes);
    1.96 +      _sizer_kind = SizerMaxAndNewSize;
    1.97 +      _adaptive_size = _min_desired_young_length == _max_desired_young_length;
    1.98 +    } else {
    1.99 +      _sizer_kind = SizerNewSizeOnly;
   1.100 +    }
   1.101 +  } else if (FLAG_IS_CMDLINE(MaxNewSize)) {
   1.102 +    _max_desired_young_length = MAX2((size_t) 1, MaxNewSize / HeapRegion::GrainBytes);
   1.103 +    _sizer_kind = SizerMaxNewSizeOnly;
   1.104 +  }
   1.105 +}
   1.106 +
   1.107 +size_t G1YoungGenSizer::calculate_default_min_length(size_t new_number_of_heap_regions) {
   1.108 +  size_t default_value = (new_number_of_heap_regions * G1DefaultMinNewGenPercent) / 100;
   1.109 +  return MAX2((size_t)1, default_value);
   1.110 +}
   1.111 +
   1.112 +size_t G1YoungGenSizer::calculate_default_max_length(size_t new_number_of_heap_regions) {
   1.113 +  size_t default_value = (new_number_of_heap_regions * G1DefaultMaxNewGenPercent) / 100;
   1.114 +  return MAX2((size_t)1, default_value);
   1.115 +}
   1.116 +
   1.117 +void G1YoungGenSizer::heap_size_changed(size_t new_number_of_heap_regions) {
   1.118 +  assert(new_number_of_heap_regions > 0, "Heap must be initialized");
   1.119 +
   1.120 +  switch (_sizer_kind) {
   1.121 +    case SizerDefaults:
   1.122 +      _min_desired_young_length = calculate_default_min_length(new_number_of_heap_regions);
   1.123 +      _max_desired_young_length = calculate_default_max_length(new_number_of_heap_regions);
   1.124 +      break;
   1.125 +    case SizerNewSizeOnly:
   1.126 +      _max_desired_young_length = calculate_default_max_length(new_number_of_heap_regions);
   1.127 +      _max_desired_young_length = MAX2(_min_desired_young_length, _max_desired_young_length);
   1.128 +      break;
   1.129 +    case SizerMaxNewSizeOnly:
   1.130 +      _min_desired_young_length = calculate_default_min_length(new_number_of_heap_regions);
   1.131 +      _min_desired_young_length = MIN2(_min_desired_young_length, _max_desired_young_length);
   1.132 +      break;
   1.133 +    case SizerMaxAndNewSize:
   1.134 +      // Do nothing. Values set on the command line, don't update them at runtime.
   1.135 +      break;
   1.136 +    case SizerNewRatio:
   1.137 +      _min_desired_young_length = new_number_of_heap_regions / (NewRatio + 1);
   1.138 +      _max_desired_young_length = _min_desired_young_length;
   1.139 +      break;
   1.140 +    default:
   1.141 +      ShouldNotReachHere();
   1.142 +  }
   1.143 +
   1.144    assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values");
   1.145 -
   1.146 -  set_adaptive_young_list_length(_min_desired_young_length < _max_desired_young_length);
   1.147 +}
   1.148 +
   1.149 +void G1CollectorPolicy::init() {
   1.150 +  // Set aside an initial future to_space.
   1.151 +  _g1 = G1CollectedHeap::heap();
   1.152 +
   1.153 +  assert(Heap_lock->owned_by_self(), "Locking discipline.");
   1.154 +
   1.155 +  initialize_gc_policy_counters();
   1.156 +
   1.157    if (adaptive_young_list_length()) {
   1.158      _young_list_fixed_length = 0;
   1.159    } else {
   1.160 -    assert(_min_desired_young_length == _max_desired_young_length, "Min and max young size differ");
   1.161 -    _young_list_fixed_length = _min_desired_young_length;
   1.162 +    _young_list_fixed_length = _young_gen_sizer->min_desired_young_length();
   1.163    }
   1.164    _free_regions_at_end_of_collection = _g1->free_regions();
   1.165    update_young_list_target_length();
   1.166 @@ -543,11 +555,7 @@
   1.167    // smaller than 1.0) we'll get 1.
   1.168    _reserve_regions = (size_t) ceil(reserve_regions_d);
   1.169  
   1.170 -  if (_using_new_ratio_calculations) {
   1.171 -    // -XX:NewRatio was specified so we need to update the
   1.172 -    // young gen length when the heap size has changed.
   1.173 -    update_young_list_size_using_newratio(new_number_of_regions);
   1.174 -  }
   1.175 +  _young_gen_sizer->heap_size_changed(new_number_of_regions);
   1.176  }
   1.177  
   1.178  size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
   1.179 @@ -565,14 +573,14 @@
   1.180    }
   1.181    desired_min_length += base_min_length;
   1.182    // make sure we don't go below any user-defined minimum bound
   1.183 -  return MAX2(_min_desired_young_length, desired_min_length);
   1.184 +  return MAX2(_young_gen_sizer->min_desired_young_length(), desired_min_length);
   1.185  }
   1.186  
   1.187  size_t G1CollectorPolicy::calculate_young_list_desired_max_length() {
   1.188    // Here, we might want to also take into account any additional
   1.189    // constraints (i.e., user-defined minimum bound). Currently, we
   1.190    // effectively don't set this bound.
   1.191 -  return _max_desired_young_length;
   1.192 +  return _young_gen_sizer->max_desired_young_length();
   1.193  }
   1.194  
   1.195  void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {

mercurial