< prev index next >

src/hotspot/share/gc/z/zDirector.cpp

Print this page




  49 }
  50 
  51 bool ZDirector::is_first() const {
  52   return ZStatCycle::ncycles() == 0;
  53 }
  54 
  55 bool ZDirector::is_warm() const {
  56   return ZStatCycle::ncycles() >= 3;
  57 }
  58 
  59 bool ZDirector::rule_timer() const {
  60   if (ZCollectionInterval == 0) {
  61     // Rule disabled
  62     return false;
  63   }
  64 
  65   // Perform GC if timer has expired.
  66   const double time_since_last_gc = ZStatCycle::time_since_last();
  67   const double time_until_gc = ZCollectionInterval - time_since_last_gc;
  68 
  69   log_debug(gc, director)("Rule: Timer, Interval: %us, TimeUntilGC: %.3lfs",
  70                           ZCollectionInterval, time_until_gc);
  71 
  72   return time_until_gc <= 0;
  73 }
  74 
  75 bool ZDirector::rule_warmup() const {
  76   if (is_warm()) {
  77     // Rule disabled
  78     return false;
  79   }
  80 
  81   // Perform GC if heap usage passes 10/20/30% and no other GC has been
  82   // performed yet. This allows us to get some early samples of the GC
  83   // duration, which is needed by the other rules.
  84   const size_t max_capacity = ZHeap::heap()->soft_max_capacity();
  85   const size_t used = ZHeap::heap()->used();
  86   const double used_threshold_percent = (ZStatCycle::ncycles() + 1) * 0.1;
  87   const size_t used_threshold = max_capacity * used_threshold_percent;
  88 
  89   log_debug(gc, director)("Rule: Warmup %.0f%%, Used: " SIZE_FORMAT "MB, UsedThreshold: " SIZE_FORMAT "MB",


 116   // Calculate time until OOM given the max allocation rate and the amount
 117   // of free memory. The allocation rate is a moving average and we multiply
 118   // that with an allocation spike tolerance factor to guard against unforeseen
 119   // phase changes in the allocate rate. We then add ~3.3 sigma to account for
 120   // the allocation rate variance, which means the probability is 1 in 1000
 121   // that a sample is outside of the confidence interval.
 122   const double max_alloc_rate = (ZStatAllocRate::avg() * ZAllocationSpikeTolerance) + (ZStatAllocRate::avg_sd() * one_in_1000);
 123   const double time_until_oom = free / (max_alloc_rate + 1.0); // Plus 1.0B/s to avoid division by zero
 124 
 125   // Calculate max duration of a GC cycle. The duration of GC is a moving
 126   // average, we add ~3.3 sigma to account for the GC duration variance.
 127   const AbsSeq& duration_of_gc = ZStatCycle::normalized_duration();
 128   const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000);
 129 
 130   // Calculate time until GC given the time until OOM and max duration of GC.
 131   // We also deduct the sample interval, so that we don't overshoot the target
 132   // time and end up starting the GC too late in the next interval.
 133   const double sample_interval = 1.0 / ZStatAllocRate::sample_hz;
 134   const double time_until_gc = time_until_oom - max_duration_of_gc - sample_interval;
 135 
 136   log_debug(gc, director)("Rule: Allocation Rate, MaxAllocRate: %.3lfMB/s, Free: " SIZE_FORMAT "MB, MaxDurationOfGC: %.3lfs, TimeUntilGC: %.3lfs",
 137                           max_alloc_rate / M, free / M, max_duration_of_gc, time_until_gc);
 138 
 139   return time_until_gc <= 0;
 140 }
 141 
 142 bool ZDirector::rule_proactive() const {
 143   if (!ZProactive || !is_warm()) {
 144     // Rule disabled
 145     return false;
 146   }
 147 
 148   // Perform GC if the impact of doing so, in terms of application throughput
 149   // reduction, is considered acceptable. This rule allows us to keep the heap
 150   // size down and allow reference processing to happen even when we have a lot
 151   // of free space on the heap.
 152 
 153   // Only consider doing a proactive GC if the heap usage has grown by at least
 154   // 10% of the max capacity since the previous GC, or more than 5 minutes has
 155   // passed since the previous GC. This helps avoid superfluous GCs when running
 156   // applications with very low allocation rate.
 157   const size_t used_after_last_gc = ZStatHeap::used_at_relocate_end();
 158   const size_t used_increase_threshold = ZHeap::heap()->soft_max_capacity() * 0.10; // 10%
 159   const size_t used_threshold = used_after_last_gc + used_increase_threshold;
 160   const size_t used = ZHeap::heap()->used();
 161   const double time_since_last_gc = ZStatCycle::time_since_last();
 162   const double time_since_last_gc_threshold = 5 * 60; // 5 minutes
 163   if (used < used_threshold && time_since_last_gc < time_since_last_gc_threshold) {
 164     // Don't even consider doing a proactive GC
 165     log_debug(gc, director)("Rule: Proactive, UsedUntilEnabled: " SIZE_FORMAT "MB, TimeUntilEnabled: %.3lfs",
 166                             (used_threshold - used) / M,
 167                             time_since_last_gc_threshold - time_since_last_gc);
 168     return false;
 169   }
 170 
 171   const double assumed_throughput_drop_during_gc = 0.50; // 50%
 172   const double acceptable_throughput_drop = 0.01;        // 1%
 173   const AbsSeq& duration_of_gc = ZStatCycle::normalized_duration();
 174   const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000);
 175   const double acceptable_gc_interval = max_duration_of_gc * ((assumed_throughput_drop_during_gc / acceptable_throughput_drop) - 1.0);
 176   const double time_until_gc = acceptable_gc_interval - time_since_last_gc;
 177 
 178   log_debug(gc, director)("Rule: Proactive, AcceptableGCInterval: %.3lfs, TimeSinceLastGC: %.3lfs, TimeUntilGC: %.3lfs",
 179                           acceptable_gc_interval, time_since_last_gc, time_until_gc);
 180 
 181   return time_until_gc <= 0;
 182 }
 183 
 184 bool ZDirector::rule_high_usage() const {
 185   // Perform GC if the amount of free memory is 5% or less. This is a preventive
 186   // meassure in the case where the application has a very low allocation rate,
 187   // such that the allocation rate rule doesn't trigger, but the amount of free
 188   // memory is still slowly but surely heading towards zero. In this situation,
 189   // we start a GC cycle to avoid a potential allocation stall later.
 190 
 191   // Calculate amount of free memory available to Java threads. Note that
 192   // the heap reserve is not available to Java threads and is therefore not
 193   // considered part of the free memory.
 194   const size_t max_capacity = ZHeap::heap()->soft_max_capacity();
 195   const size_t max_reserve = ZHeap::heap()->max_reserve();
 196   const size_t used = ZHeap::heap()->used();
 197   const size_t free_with_reserve = max_capacity - used;
 198   const size_t free = free_with_reserve - MIN2(free_with_reserve, max_reserve);
 199   const double free_percent = percent_of(free, max_capacity);
 200 
 201   log_debug(gc, director)("Rule: High Usage, Free: " SIZE_FORMAT "MB(%.1lf%%)",
 202                           free / M, free_percent);
 203 
 204   return free_percent <= 5.0;
 205 }
 206 
 207 GCCause::Cause ZDirector::make_gc_decision() const {
 208   // Rule 0: Timer
 209   if (rule_timer()) {
 210     return GCCause::_z_timer;
 211   }
 212 
 213   // Rule 1: Warmup
 214   if (rule_warmup()) {
 215     return GCCause::_z_warmup;
 216   }
 217 
 218   // Rule 2: Allocation rate
 219   if (rule_allocation_rate()) {
 220     return GCCause::_z_allocation_rate;
 221   }




  49 }
  50 
  51 bool ZDirector::is_first() const {
  52   return ZStatCycle::ncycles() == 0;
  53 }
  54 
  55 bool ZDirector::is_warm() const {
  56   return ZStatCycle::ncycles() >= 3;
  57 }
  58 
  59 bool ZDirector::rule_timer() const {
  60   if (ZCollectionInterval == 0) {
  61     // Rule disabled
  62     return false;
  63   }
  64 
  65   // Perform GC if timer has expired.
  66   const double time_since_last_gc = ZStatCycle::time_since_last();
  67   const double time_until_gc = ZCollectionInterval - time_since_last_gc;
  68 
  69   log_debug(gc, director)("Rule: Timer, Interval: %us, TimeUntilGC: %.3fs",
  70                           ZCollectionInterval, time_until_gc);
  71 
  72   return time_until_gc <= 0;
  73 }
  74 
  75 bool ZDirector::rule_warmup() const {
  76   if (is_warm()) {
  77     // Rule disabled
  78     return false;
  79   }
  80 
  81   // Perform GC if heap usage passes 10/20/30% and no other GC has been
  82   // performed yet. This allows us to get some early samples of the GC
  83   // duration, which is needed by the other rules.
  84   const size_t max_capacity = ZHeap::heap()->soft_max_capacity();
  85   const size_t used = ZHeap::heap()->used();
  86   const double used_threshold_percent = (ZStatCycle::ncycles() + 1) * 0.1;
  87   const size_t used_threshold = max_capacity * used_threshold_percent;
  88 
  89   log_debug(gc, director)("Rule: Warmup %.0f%%, Used: " SIZE_FORMAT "MB, UsedThreshold: " SIZE_FORMAT "MB",


 116   // Calculate time until OOM given the max allocation rate and the amount
 117   // of free memory. The allocation rate is a moving average and we multiply
 118   // that with an allocation spike tolerance factor to guard against unforeseen
 119   // phase changes in the allocate rate. We then add ~3.3 sigma to account for
 120   // the allocation rate variance, which means the probability is 1 in 1000
 121   // that a sample is outside of the confidence interval.
 122   const double max_alloc_rate = (ZStatAllocRate::avg() * ZAllocationSpikeTolerance) + (ZStatAllocRate::avg_sd() * one_in_1000);
 123   const double time_until_oom = free / (max_alloc_rate + 1.0); // Plus 1.0B/s to avoid division by zero
 124 
 125   // Calculate max duration of a GC cycle. The duration of GC is a moving
 126   // average, we add ~3.3 sigma to account for the GC duration variance.
 127   const AbsSeq& duration_of_gc = ZStatCycle::normalized_duration();
 128   const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000);
 129 
 130   // Calculate time until GC given the time until OOM and max duration of GC.
 131   // We also deduct the sample interval, so that we don't overshoot the target
 132   // time and end up starting the GC too late in the next interval.
 133   const double sample_interval = 1.0 / ZStatAllocRate::sample_hz;
 134   const double time_until_gc = time_until_oom - max_duration_of_gc - sample_interval;
 135 
 136   log_debug(gc, director)("Rule: Allocation Rate, MaxAllocRate: %.3fMB/s, Free: " SIZE_FORMAT "MB, MaxDurationOfGC: %.3fs, TimeUntilGC: %.3fs",
 137                           max_alloc_rate / M, free / M, max_duration_of_gc, time_until_gc);
 138 
 139   return time_until_gc <= 0;
 140 }
 141 
 142 bool ZDirector::rule_proactive() const {
 143   if (!ZProactive || !is_warm()) {
 144     // Rule disabled
 145     return false;
 146   }
 147 
 148   // Perform GC if the impact of doing so, in terms of application throughput
 149   // reduction, is considered acceptable. This rule allows us to keep the heap
 150   // size down and allow reference processing to happen even when we have a lot
 151   // of free space on the heap.
 152 
 153   // Only consider doing a proactive GC if the heap usage has grown by at least
 154   // 10% of the max capacity since the previous GC, or more than 5 minutes has
 155   // passed since the previous GC. This helps avoid superfluous GCs when running
 156   // applications with very low allocation rate.
 157   const size_t used_after_last_gc = ZStatHeap::used_at_relocate_end();
 158   const size_t used_increase_threshold = ZHeap::heap()->soft_max_capacity() * 0.10; // 10%
 159   const size_t used_threshold = used_after_last_gc + used_increase_threshold;
 160   const size_t used = ZHeap::heap()->used();
 161   const double time_since_last_gc = ZStatCycle::time_since_last();
 162   const double time_since_last_gc_threshold = 5 * 60; // 5 minutes
 163   if (used < used_threshold && time_since_last_gc < time_since_last_gc_threshold) {
 164     // Don't even consider doing a proactive GC
 165     log_debug(gc, director)("Rule: Proactive, UsedUntilEnabled: " SIZE_FORMAT "MB, TimeUntilEnabled: %.3fs",
 166                             (used_threshold - used) / M,
 167                             time_since_last_gc_threshold - time_since_last_gc);
 168     return false;
 169   }
 170 
 171   const double assumed_throughput_drop_during_gc = 0.50; // 50%
 172   const double acceptable_throughput_drop = 0.01;        // 1%
 173   const AbsSeq& duration_of_gc = ZStatCycle::normalized_duration();
 174   const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000);
 175   const double acceptable_gc_interval = max_duration_of_gc * ((assumed_throughput_drop_during_gc / acceptable_throughput_drop) - 1.0);
 176   const double time_until_gc = acceptable_gc_interval - time_since_last_gc;
 177 
 178   log_debug(gc, director)("Rule: Proactive, AcceptableGCInterval: %.3fs, TimeSinceLastGC: %.3fs, TimeUntilGC: %.3fs",
 179                           acceptable_gc_interval, time_since_last_gc, time_until_gc);
 180 
 181   return time_until_gc <= 0;
 182 }
 183 
 184 bool ZDirector::rule_high_usage() const {
 185   // Perform GC if the amount of free memory is 5% or less. This is a preventive
 186   // meassure in the case where the application has a very low allocation rate,
 187   // such that the allocation rate rule doesn't trigger, but the amount of free
 188   // memory is still slowly but surely heading towards zero. In this situation,
 189   // we start a GC cycle to avoid a potential allocation stall later.
 190 
 191   // Calculate amount of free memory available to Java threads. Note that
 192   // the heap reserve is not available to Java threads and is therefore not
 193   // considered part of the free memory.
 194   const size_t max_capacity = ZHeap::heap()->soft_max_capacity();
 195   const size_t max_reserve = ZHeap::heap()->max_reserve();
 196   const size_t used = ZHeap::heap()->used();
 197   const size_t free_with_reserve = max_capacity - used;
 198   const size_t free = free_with_reserve - MIN2(free_with_reserve, max_reserve);
 199   const double free_percent = percent_of(free, max_capacity);
 200 
 201   log_debug(gc, director)("Rule: High Usage, Free: " SIZE_FORMAT "MB(%.1f%%)",
 202                           free / M, free_percent);
 203 
 204   return free_percent <= 5.0;
 205 }
 206 
 207 GCCause::Cause ZDirector::make_gc_decision() const {
 208   // Rule 0: Timer
 209   if (rule_timer()) {
 210     return GCCause::_z_timer;
 211   }
 212 
 213   // Rule 1: Warmup
 214   if (rule_warmup()) {
 215     return GCCause::_z_warmup;
 216   }
 217 
 218   // Rule 2: Allocation rate
 219   if (rule_allocation_rate()) {
 220     return GCCause::_z_allocation_rate;
 221   }


< prev index next >