|
22 | 22 | * questions. |
23 | 23 | * |
24 | 24 | */ |
25 | | -#include "precompiled.hpp" |
26 | 25 |
|
| 26 | +#include "precompiled.hpp" |
27 | 27 |
|
28 | 28 | #include "gc/shared/gcCause.hpp" |
29 | 29 | #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" |
@@ -205,6 +205,34 @@ static double saturate(double value, double min, double max) { |
205 | 205 | return MAX2(MIN2(value, max), min); |
206 | 206 | } |
207 | 207 |
|
| 208 | +// Rationale: |
| 209 | +// The idea is that there is an average allocation rate and there are occasional abnormal bursts (or spikes) of |
| 210 | +// allocations that exceed the average allocation rate. What do these spikes look like? |
| 211 | +// |
| 212 | +// 1. At certain phase changes, we may discard large amounts of data and replace it with large numbers of newly |
| 213 | +// allocated objects. This "spike" looks more like a phase change. We were in steady state at M bytes/sec |
| 214 | +// allocation rate and now we're in a "reinitialization phase" that looks like N bytes/sec. We need the "spike" |
| 215 | +// accommodation to give us enough runway to recalibrate our "average allocation rate". |
| 216 | +// |
| 217 | +// 2. The typical workload changes. "Suddenly", our typical workload of N TPS increases to N+delta TPS. This means |
| 218 | +// our average allocation rate needs to be adjusted. Once again, we need the "spike" accomodation to give us |
| 219 | +// enough runway to recalibrate our "average allocation rate". |
| 220 | +// |
| 221 | +// 3. Though there is an "average" allocation rate, a given workload's demand for allocation may be very bursty. We |
| 222 | +// allocate a bunch of LABs during the 5 ms that follow completion of a GC, then we perform no more allocations for |
| 223 | +// the next 150 ms. It seems we want the "spike" to represent the maximum divergence from average within the |
| 224 | +// period of time between consecutive evaluation of the should_start_gc() service. Here's the thinking: |
| 225 | +// |
| 226 | +// a) Between now and the next time I ask whether should_start_gc(), we might experience a spike representing |
| 227 | +// the anticipated burst of allocations. If that would put us over budget, then we should start GC immediately. |
| 228 | +// b) Between now and the anticipated depletion of allocation pool, there may be two or more bursts of allocations. |
| 229 | +// If there are more than one of these bursts, we can "approximate" that these will be separated by spans of |
| 230 | +// time with very little or no allocations so the "average" allocation rate should be a suitable approximation |
| 231 | +// of how this will behave. |
| 232 | +// |
| 233 | +// For cases 1 and 2, we need to "quickly" recalibrate the average allocation rate whenever we detect a change |
| 234 | +// in operation mode. We want some way to decide that the average rate has changed, while keeping average |
| 235 | +// allocation rate computation independent. |
208 | 236 | bool ShenandoahAdaptiveHeuristics::should_start_gc() { |
209 | 237 | size_t capacity = _space_info->soft_max_capacity(); |
210 | 238 | size_t available = _space_info->soft_available(); |
@@ -238,34 +266,6 @@ bool ShenandoahAdaptiveHeuristics::should_start_gc() { |
238 | 266 | return true; |
239 | 267 | } |
240 | 268 | } |
241 | | - // Rationale: |
242 | | - // The idea is that there is an average allocation rate and there are occasional abnormal bursts (or spikes) of |
243 | | - // allocations that exceed the average allocation rate. What do these spikes look like? |
244 | | - // |
245 | | - // 1. At certain phase changes, we may discard large amounts of data and replace it with large numbers of newly |
246 | | - // allocated objects. This "spike" looks more like a phase change. We were in steady state at M bytes/sec |
247 | | - // allocation rate and now we're in a "reinitialization phase" that looks like N bytes/sec. We need the "spike" |
248 | | - // accommodation to give us enough runway to recalibrate our "average allocation rate". |
249 | | - // |
250 | | - // 2. The typical workload changes. "Suddenly", our typical workload of N TPS increases to N+delta TPS. This means |
251 | | - // our average allocation rate needs to be adjusted. Once again, we need the "spike" accomodation to give us |
252 | | - // enough runway to recalibrate our "average allocation rate". |
253 | | - // |
254 | | - // 3. Though there is an "average" allocation rate, a given workload's demand for allocation may be very bursty. We |
255 | | - // allocate a bunch of LABs during the 5 ms that follow completion of a GC, then we perform no more allocations for |
256 | | - // the next 150 ms. It seems we want the "spike" to represent the maximum divergence from average within the |
257 | | - // period of time between consecutive evaluation of the should_start_gc() service. Here's the thinking: |
258 | | - // |
259 | | - // a) Between now and the next time I ask whether should_start_gc(), we might experience a spike representing |
260 | | - // the anticipated burst of allocations. If that would put us over budget, then we should start GC immediately. |
261 | | - // b) Between now and the anticipated depletion of allocation pool, there may be two or more bursts of allocations. |
262 | | - // If there are more than one of these bursts, we can "approximate" that these will be separated by spans of |
263 | | - // time with very little or no allocations so the "average" allocation rate should be a suitable approximation |
264 | | - // of how this will behave. |
265 | | - // |
266 | | - // For cases 1 and 2, we need to "quickly" recalibrate the average allocation rate whenever we detect a change |
267 | | - // in operation mode. We want some way to decide that the average rate has changed. Make average allocation rate |
268 | | - // computations an independent effort. |
269 | 269 | // Check if allocation headroom is still okay. This also factors in: |
270 | 270 | // 1. Some space to absorb allocation spikes (ShenandoahAllocSpikeFactor) |
271 | 271 | // 2. Accumulated penalties from Degenerated and Full GC |
|
0 commit comments