Print this page
G1: Use SoftMaxHeapSize to guide GC heuristics

Split Close
Expand all
Collapse all
          --- old/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp
          +++ new/src/hotspot/share/gc/g1/g1HeapSizingPolicy.cpp
↓ open down ↓ 18 lines elided ↑ open up ↑
  19   19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20   20   * or visit www.oracle.com if you need additional information or have any
  21   21   * questions.
  22   22   *
  23   23   */
  24   24  
  25   25  #include "precompiled.hpp"
  26   26  #include "gc/g1/g1CollectedHeap.hpp"
  27   27  #include "gc/g1/g1HeapSizingPolicy.hpp"
  28   28  #include "gc/g1/g1Analytics.hpp"
       29 +#include "gc/g1/g1Policy.hpp"
  29   30  #include "logging/log.hpp"
  30   31  #include "runtime/globals.hpp"
  31   32  #include "utilities/debug.hpp"
  32   33  #include "utilities/globalDefinitions.hpp"
  33   34  
  34   35  G1HeapSizingPolicy* G1HeapSizingPolicy::create(const G1CollectedHeap* g1h, const G1Analytics* analytics) {
  35   36    return new G1HeapSizingPolicy(g1h, analytics);
  36   37  }
  37   38  
  38   39  G1HeapSizingPolicy::G1HeapSizingPolicy(const G1CollectedHeap* g1h, const G1Analytics* analytics) :
  39   40    _g1h(g1h),
  40   41    _analytics(analytics),
  41      -  _num_prev_pauses_for_heuristics(analytics->number_of_recorded_pause_times()) {
       42 +  _num_prev_pauses_for_heuristics(analytics->number_of_recorded_pause_times()),
       43 +  _minimum_desired_bytes_after_last_cm(MinHeapSize) {
  42   44  
  43   45    assert(MinOverThresholdForGrowth < _num_prev_pauses_for_heuristics, "Threshold must be less than %u", _num_prev_pauses_for_heuristics);
  44   46    clear_ratio_check_data();
  45   47  }
  46   48  
  47   49  void G1HeapSizingPolicy::clear_ratio_check_data() {
  48   50    _ratio_over_threshold_count = 0;
  49   51    _ratio_over_threshold_sum = 0.0;
  50   52    _pauses_since_start = 0;
  51   53  }
  52   54  
  53      -size_t G1HeapSizingPolicy::expansion_amount() {
       55 +size_t G1HeapSizingPolicy::expansion_amount_after_young_collection() {
  54   56    double recent_gc_overhead = _analytics->recent_avg_pause_time_ratio() * 100.0;
  55   57    double last_gc_overhead = _analytics->last_pause_time_ratio() * 100.0;
  56   58    assert(GCTimeRatio > 0,
  57   59           "we should have set it to a default value set_g1_gc_flags() "
  58   60           "if a user set it to 0");
  59   61    const double gc_overhead_percent = 100.0 * (1.0 / (1.0 + GCTimeRatio));
  60   62  
  61   63    double threshold = gc_overhead_percent;
  62   64    size_t expand_bytes = 0;
  63   65  
↓ open down ↓ 88 lines elided ↑ open up ↑
 152  154      // start again the next time we see a ratio above the threshold.
 153  155      if (_ratio_over_threshold_count > 0) {
 154  156        _pauses_since_start++;
 155  157        if (_pauses_since_start > _num_prev_pauses_for_heuristics) {
 156  158          clear_ratio_check_data();
 157  159        }
 158  160      }
 159  161    }
 160  162  
 161  163    return expand_bytes;
      164 +}
      165 +
      166 +size_t G1HeapSizingPolicy::target_heap_capacity(size_t used_bytes,  uintx free_ratio) {
      167 +  const double free_percentage = (double) free_ratio / 100.0;
      168 +  const double used_percentage = 1.0 - free_percentage;
      169 +
      170 +  // We have to be careful here as these two calculations can overflow
      171 +  // 32-bit size_t's.
      172 +  double used_bytes_d = (double) used_bytes;
      173 +  double desired_capacity_d = used_bytes_d / used_percentage;
      174 +  // Let's make sure that they are both under the max heap size, which
      175 +  // by default will make it fit into a size_t.
      176 +  double desired_capacity_upper_bound = (double) MaxHeapSize;
      177 +  desired_capacity_d = MIN2(desired_capacity_d, desired_capacity_upper_bound);
      178 +  // We can now safely turn it into size_t's.
      179 +  return (size_t) desired_capacity_d;
      180 +}
      181 +
      182 +size_t G1HeapSizingPolicy::expansion_amount_after_concurrent_mark() {
      183 +  size_t cur_used_bytes = _g1h->non_young_capacity_bytes();
      184 +
      185 +  size_t minimum_desired_capacity = target_heap_capacity(cur_used_bytes, MinHeapFreeRatio);
      186 +
      187 +  _minimum_desired_bytes_after_last_cm = _g1h->policy()->minimum_desired_bytes_after_concurrent_mark(cur_used_bytes);
      188 +  // Use the smaller one between minimum_desired_capacity
      189 +  // and predicted minimum_desired_bytes_after_concurrent_mark
      190 +  // We still use minimum_desired_capacity because minimum_desired_bytes_after_concurrent_mark
      191 +  // might include a lot of new allocated humongous objects
      192 +  _minimum_desired_bytes_after_last_cm = MIN2(_minimum_desired_bytes_after_last_cm, minimum_desired_capacity);
      193 +
      194 +  return _minimum_desired_bytes_after_last_cm > _g1h->capacity() ?
      195 +         _minimum_desired_bytes_after_last_cm - _g1h->capacity() : 0;
      196 +}
      197 +
      198 +size_t G1HeapSizingPolicy::shrink_amount_after_mixed_collections() {
      199 +  size_t shrink_bytes = 0;
      200 +  const size_t capacity_after_gc = _g1h->capacity();
      201 +  const size_t used_after_gc = capacity_after_gc - _g1h->unused_committed_regions_in_bytes();
      202 +  size_t maximum_desired_capacity = target_heap_capacity(used_after_gc, MaxHeapFreeRatio);
      203 +  // soft_max_capacity can be smaller
      204 +  maximum_desired_capacity = MIN2(maximum_desired_capacity, _g1h->soft_max_capacity());
      205 +  // Make sure not less than _minimum_desired_bytes_after_last_cm
      206 +  maximum_desired_capacity = MAX2(maximum_desired_capacity, _minimum_desired_bytes_after_last_cm);
      207 +
      208 +  if (capacity_after_gc > maximum_desired_capacity) {
      209 +    shrink_bytes = capacity_after_gc - maximum_desired_capacity;
      210 +  }
      211 +
      212 +  return shrink_bytes;
 162  213  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX