107 // Calculate amount of free memory available to Java threads. Note that
108 // the heap reserve is not available to Java threads and is therefore not
109 // considered part of the free memory.
110 const size_t max_capacity = ZHeap::heap()->max_capacity();
111 const size_t max_reserve = ZHeap::heap()->max_reserve();
112 const size_t used = ZHeap::heap()->used();
113 const size_t free_with_reserve = max_capacity - used;
114 const size_t free = free_with_reserve - MIN2(free_with_reserve, max_reserve);
115
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 alllcation spike tolerance factor to guard against unforseen
119 // phase changes in the allocate rate. We then add ~3.3 sigma to account for
120 // the allocation rate variance, which means the probablility 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::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 (!is_warm()) {
144 // Rule disabled
145 return false;
146 }
147
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()->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 return false;
166 }
167
168 const double assumed_throughput_drop_during_gc = 0.50; // 50%
169 const double acceptable_throughput_drop = 0.01; // 1%
170 const AbsSeq& duration_of_gc = ZStatCycle::duration();
171 const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000);
172 const double acceptable_gc_interval = max_duration_of_gc * ((assumed_throughput_drop_during_gc / acceptable_throughput_drop) - 1.0);
173 const double time_until_gc = acceptable_gc_interval - time_since_last_gc;
174
175 log_debug(gc, director)("Rule: Proactive, AcceptableGCInterval: %.3lfs, TimeSinceLastGC: %.3lfs, TimeUntilGC: %.3lfs",
176 acceptable_gc_interval, time_since_last_gc, time_until_gc);
177
178 return time_until_gc <= 0;
179 }
180
181 GCCause::Cause ZDirector::make_gc_decision() const {
182 // Rule 0: Timer
183 if (rule_timer()) {
184 return GCCause::_z_timer;
185 }
186
187 // Rule 1: Warmup
188 if (rule_warmup()) {
189 return GCCause::_z_warmup;
190 }
|
107 // Calculate amount of free memory available to Java threads. Note that
108 // the heap reserve is not available to Java threads and is therefore not
109 // considered part of the free memory.
110 const size_t max_capacity = ZHeap::heap()->max_capacity();
111 const size_t max_reserve = ZHeap::heap()->max_reserve();
112 const size_t used = ZHeap::heap()->used();
113 const size_t free_with_reserve = max_capacity - used;
114 const size_t free = free_with_reserve - MIN2(free_with_reserve, max_reserve);
115
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 alllcation spike tolerance factor to guard against unforseen
119 // phase changes in the allocate rate. We then add ~3.3 sigma to account for
120 // the allocation rate variance, which means the probablility 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 (!is_warm()) {
144 // Rule disabled
145 return false;
146 }
147
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()->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 return false;
166 }
167
168 const double assumed_throughput_drop_during_gc = 0.50; // 50%
169 const double acceptable_throughput_drop = 0.01; // 1%
170 const AbsSeq& duration_of_gc = ZStatCycle::normalized_duration();
171 const double max_duration_of_gc = duration_of_gc.davg() + (duration_of_gc.dsd() * one_in_1000);
172 const double acceptable_gc_interval = max_duration_of_gc * ((assumed_throughput_drop_during_gc / acceptable_throughput_drop) - 1.0);
173 const double time_until_gc = acceptable_gc_interval - time_since_last_gc;
174
175 log_debug(gc, director)("Rule: Proactive, AcceptableGCInterval: %.3lfs, TimeSinceLastGC: %.3lfs, TimeUntilGC: %.3lfs",
176 acceptable_gc_interval, time_since_last_gc, time_until_gc);
177
178 return time_until_gc <= 0;
179 }
180
181 GCCause::Cause ZDirector::make_gc_decision() const {
182 // Rule 0: Timer
183 if (rule_timer()) {
184 return GCCause::_z_timer;
185 }
186
187 // Rule 1: Warmup
188 if (rule_warmup()) {
189 return GCCause::_z_warmup;
190 }
|