8142484: Let IHOP follow the current capacity, not the maximum capacity
authortschatzl
Mon, 07 Mar 2016 10:56:06 +0100
changeset 36577 e177c49493e9
parent 36576 8bd19bf60177
child 36578 f1c78adfcdd2
8142484: Let IHOP follow the current capacity, not the maximum capacity Summary: Instead of following the current heap capacity, let all IHOP calculations follow the maximum capacity. Reviewed-by: brutisso, jmasa
hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp
hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp
hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Tue Mar 01 12:10:50 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp	Mon Mar 07 10:56:06 2016 +0100
@@ -269,6 +269,8 @@
   _reserve_regions = 0;
 
   _cset_chooser = new CollectionSetChooser();
+
+  _ihop_control = create_ihop_control();
 }
 
 G1CollectorPolicy::~G1CollectorPolicy() {
@@ -469,8 +471,6 @@
   if (max_young_size != MaxNewSize) {
     FLAG_SET_ERGO(size_t, MaxNewSize, max_young_size);
   }
-
-  _ihop_control = create_ihop_control();
 }
 
 void G1CollectorPolicy::initialize_flags() {
@@ -565,6 +565,8 @@
   _reserve_regions = (uint) ceil(reserve_regions_d);
 
   _young_gen_sizer->heap_size_changed(new_number_of_regions);
+
+  _ihop_control->update_target_occupancy(new_number_of_regions * HeapRegion::GrainBytes);
 }
 
 uint G1CollectorPolicy::calculate_young_list_desired_min_length(
@@ -1234,13 +1236,11 @@
 G1IHOPControl* G1CollectorPolicy::create_ihop_control() const {
   if (G1UseAdaptiveIHOP) {
     return new G1AdaptiveIHOPControl(InitiatingHeapOccupancyPercent,
-                                     G1CollectedHeap::heap()->max_capacity(),
                                      &_predictor,
                                      G1ReservePercent,
                                      G1HeapWastePercent);
   } else {
-    return new G1StaticIHOPControl(InitiatingHeapOccupancyPercent,
-                                   G1CollectedHeap::heap()->max_capacity());
+    return new G1StaticIHOPControl(InitiatingHeapOccupancyPercent);
   }
 }
 
--- a/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp	Tue Mar 01 12:10:50 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/g1IHOPControl.cpp	Mon Mar 07 10:56:06 2016 +0100
@@ -29,15 +29,21 @@
 #include "gc/shared/gcTrace.hpp"
 #include "logging/log.hpp"
 
-G1IHOPControl::G1IHOPControl(double initial_ihop_percent, size_t target_occupancy) :
+G1IHOPControl::G1IHOPControl(double initial_ihop_percent) :
   _initial_ihop_percent(initial_ihop_percent),
-  _target_occupancy(target_occupancy),
+  _target_occupancy(0),
   _last_allocated_bytes(0),
   _last_allocation_time_s(0.0)
 {
   assert(_initial_ihop_percent >= 0.0 && _initial_ihop_percent <= 100.0, "Initial IHOP value must be between 0 and 100 but is %.3f", initial_ihop_percent);
 }
 
+void G1IHOPControl::update_target_occupancy(size_t new_target_occupancy) {
+  log_debug(gc, ihop)("Target occupancy update: old: " SIZE_FORMAT "B, new: " SIZE_FORMAT "B",
+                      _target_occupancy, new_target_occupancy);
+  _target_occupancy = new_target_occupancy;
+}
+
 void G1IHOPControl::update_allocation_info(double allocation_time_s, size_t allocated_bytes, size_t additional_buffer_size) {
   assert(allocation_time_s >= 0.0, "Allocation time must be positive but is %.3f", allocation_time_s);
 
@@ -46,6 +52,7 @@
 }
 
 void G1IHOPControl::print() {
+  assert(_target_occupancy > 0, "Target occupancy still not updated yet.");
   size_t cur_conc_mark_start_threshold = get_conc_mark_start_threshold();
   log_debug(gc, ihop)("Basic information (value update), threshold: " SIZE_FORMAT "B (%1.2f), target occupancy: " SIZE_FORMAT "B, current occupancy: " SIZE_FORMAT "B, "
                       "recent allocation size: " SIZE_FORMAT "B, recent allocation duration: %1.2fms, recent old gen allocation rate: %1.2fB/s, recent marking phase length: %1.2fms",
@@ -60,6 +67,7 @@
 }
 
 void G1IHOPControl::send_trace_event(G1NewTracer* tracer) {
+  assert(_target_occupancy > 0, "Target occupancy still not updated yet.");
   tracer->report_basic_ihop_statistics(get_conc_mark_start_threshold(),
                                        _target_occupancy,
                                        G1CollectedHeap::heap()->used(),
@@ -68,10 +76,9 @@
                                        last_marking_length_s());
 }
 
-G1StaticIHOPControl::G1StaticIHOPControl(double ihop_percent, size_t target_occupancy) :
-  G1IHOPControl(ihop_percent, target_occupancy),
+G1StaticIHOPControl::G1StaticIHOPControl(double ihop_percent) :
+  G1IHOPControl(ihop_percent),
   _last_marking_length_s(0.0) {
-  assert(_target_occupancy > 0, "Target occupancy must be larger than zero.");
 }
 
 #ifndef PRODUCT
@@ -85,7 +92,8 @@
 void G1StaticIHOPControl::test() {
   size_t const initial_ihop = 45;
 
-  G1StaticIHOPControl ctrl(initial_ihop, 100);
+  G1StaticIHOPControl ctrl(initial_ihop);
+  ctrl.update_target_occupancy(100);
 
   size_t threshold = ctrl.get_conc_mark_start_threshold();
   assert(threshold == initial_ihop,
@@ -115,11 +123,10 @@
 #endif
 
 G1AdaptiveIHOPControl::G1AdaptiveIHOPControl(double ihop_percent,
-                                             size_t initial_target_occupancy,
                                              G1Predictions const* predictor,
                                              size_t heap_reserve_percent,
                                              size_t heap_waste_percent) :
-  G1IHOPControl(ihop_percent, initial_target_occupancy),
+  G1IHOPControl(ihop_percent),
   _predictor(predictor),
   _marking_times_s(10, 0.95),
   _allocation_rate_s(10, 0.95),
@@ -130,6 +137,7 @@
 }
 
 size_t G1AdaptiveIHOPControl::actual_target_threshold() const {
+  guarantee(_target_occupancy > 0, "Target occupancy still not updated yet.");
   // The actual target threshold takes the heap reserve and the expected waste in
   // free space  into account.
   // _heap_reserve is that part of the total heap capacity that is reserved for
@@ -227,7 +235,8 @@
   // target_size - (young_size + alloc_amount/alloc_time * marking_time)
 
   G1Predictions pred(0.95);
-  G1AdaptiveIHOPControl ctrl(initial_threshold, target_size, &pred, 0, 0);
+  G1AdaptiveIHOPControl ctrl(initial_threshold, &pred, 0, 0);
+  ctrl.update_target_occupancy(target_size);
 
   // First "load".
   size_t const alloc_time1 = 2;
@@ -288,5 +297,6 @@
 
 void IHOP_test() {
   G1StaticIHOPControl::test();
+  G1AdaptiveIHOPControl::test();
 }
 #endif
--- a/hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp	Tue Mar 01 12:10:50 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/g1IHOPControl.hpp	Mon Mar 07 10:56:06 2016 +0100
@@ -38,7 +38,8 @@
  protected:
   // The initial IHOP value relative to the target occupancy.
   double _initial_ihop_percent;
-  // The target maximum occupancy of the heap.
+  // The target maximum occupancy of the heap. The target occupancy is the number
+  // of bytes when marking should be finished and reclaim started.
   size_t _target_occupancy;
 
   // Most recent complete mutator allocation period in seconds.
@@ -46,10 +47,9 @@
   // Amount of bytes allocated during _last_allocation_time_s.
   size_t _last_allocated_bytes;
 
-  // Initialize an instance with the initial IHOP value in percent and the target
-  // occupancy. The target occupancy is the number of bytes when marking should
-  // be finished and reclaim started.
-  G1IHOPControl(double initial_ihop_percent, size_t target_occupancy);
+  // Initialize an instance with the initial IHOP value in percent. The target
+  // occupancy will be updated at the first heap expansion.
+  G1IHOPControl(double initial_ihop_percent);
 
   // Most recent time from the end of the initial mark to the start of the first
   // mixed gc.
@@ -60,6 +60,8 @@
   // Get the current non-young occupancy at which concurrent marking should start.
   virtual size_t get_conc_mark_start_threshold() = 0;
 
+  // Adjust target occupancy.
+  virtual void update_target_occupancy(size_t new_target_occupancy);
   // Update information about time during which allocations in the Java heap occurred,
   // how large these allocations were in bytes, and an additional buffer.
   // The allocations should contain any amount of space made unusable for further
@@ -86,9 +88,12 @@
  protected:
   double last_marking_length_s() const { return _last_marking_length_s; }
  public:
-  G1StaticIHOPControl(double ihop_percent, size_t target_occupancy);
+  G1StaticIHOPControl(double ihop_percent);
 
-  size_t get_conc_mark_start_threshold() { return (size_t) (_initial_ihop_percent * _target_occupancy / 100.0); }
+  size_t get_conc_mark_start_threshold() {
+    guarantee(_target_occupancy > 0, "Target occupancy must have been initialized.");
+    return (size_t) (_initial_ihop_percent * _target_occupancy / 100.0);
+  }
 
   virtual void update_marking_length(double marking_length_s) {
    assert(marking_length_s > 0.0, "Marking length must be larger than zero but is %.3f", marking_length_s);
@@ -132,7 +137,6 @@
   virtual double last_marking_length_s() const { return _marking_times_s.last(); }
  public:
   G1AdaptiveIHOPControl(double ihop_percent,
-                        size_t initial_target_occupancy,
                         G1Predictions const* predictor,
                         size_t heap_reserve_percent, // The percentage of total heap capacity that should not be tapped into.
                         size_t heap_waste_percent);  // The percentage of the free space in the heap that we think is not usable for allocation.