36 // _throughput_goal = 1 - ( 1 / (1 + gc_cost_ratio))
37 // gc_cost_ratio is the ratio
38 // application cost / gc cost
39 // For example a gc_cost_ratio of 4 translates into a
40 // throughput goal of .80
41
42 AdaptiveSizePolicy::AdaptiveSizePolicy(size_t init_eden_size,
43 size_t init_promo_size,
44 size_t init_survivor_size,
45 double gc_pause_goal_sec,
46 uint gc_cost_ratio) :
47 _throughput_goal(1.0 - double(1.0 / (1.0 + (double) gc_cost_ratio))),
48 _eden_size(init_eden_size),
49 _promo_size(init_promo_size),
50 _survivor_size(init_survivor_size),
51 _latest_minor_mutator_interval_seconds(0),
52 _threshold_tolerance_percent(1.0 + ThresholdTolerance/100.0),
53 _gc_pause_goal_sec(gc_pause_goal_sec),
54 _young_gen_change_for_minor_throughput(0),
55 _old_gen_change_for_major_throughput(0) {
56 assert(AdaptiveSizePolicyGCTimeLimitThreshold > 0,
57 "No opportunity to clear SoftReferences before GC overhead limit");
58 _avg_minor_pause =
59 new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding);
60 _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
61 _avg_minor_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
62 _avg_major_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
63
64 _avg_young_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
65 _avg_old_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
66 _avg_eden_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
67
68 _avg_survived = new AdaptivePaddedAverage(AdaptiveSizePolicyWeight,
69 SurvivorPadding);
70 _avg_pretenured = new AdaptivePaddedNoZeroDevAverage(
71 AdaptiveSizePolicyWeight,
72 SurvivorPadding);
73
74 _minor_pause_old_estimator =
75 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
76 _minor_pause_young_estimator =
77 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
256 avg_major_interval, time_since_last_major_gc);
257 log_trace(gc, ergo)(" major gc cost: %f decayed major gc cost: %f",
258 major_gc_cost(), decayed_major_gc_cost);
259 }
260 }
261 double result = MIN2(1.0, decayed_major_gc_cost + minor_gc_cost());
262 return result;
263 }
264
265
266 void AdaptiveSizePolicy::clear_generation_free_space_flags() {
267 set_change_young_gen_for_min_pauses(0);
268 set_change_old_gen_for_maj_pauses(0);
269
270 set_change_old_gen_for_throughput(0);
271 set_change_young_gen_for_throughput(0);
272 set_decrease_for_footprint(0);
273 set_decide_at_full_gc(0);
274 }
275
276 class AdaptiveSizePolicyTimeOverheadTester: public OverheadTester {
277 double _gc_cost;
278
279 public:
280 AdaptiveSizePolicyTimeOverheadTester(double gc_cost) : _gc_cost(gc_cost) {}
281
282 bool is_exceeded() {
283 // Note that the gc time limit test only works for the collections
284 // of the young gen + tenured gen and not for collections of the
285 // permanent gen. That is because the calculation of the space
286 // freed by the collection is the free space in the young gen +
287 // tenured gen.
288 return _gc_cost > (GCTimeLimit / 100.0);
289 }
290 };
291
292 class AdaptiveSizePolicySpaceOverheadTester: public OverheadTester {
293 size_t _eden_live;
294 size_t _max_old_gen_size;
295 size_t _max_eden_size;
296 size_t _promo_size;
297 double _avg_eden_live;
298 double _avg_old_live;
299
300 public:
301 AdaptiveSizePolicySpaceOverheadTester(size_t eden_live,
302 size_t max_old_gen_size,
303 size_t max_eden_size,
304 size_t promo_size,
305 double avg_eden_live,
306 double avg_old_live) :
307 _eden_live(eden_live),
308 _max_old_gen_size(max_old_gen_size),
309 _max_eden_size(max_eden_size),
310 _promo_size(promo_size),
311 _avg_eden_live(avg_eden_live),
312 _avg_old_live(avg_old_live) {}
342 size_t promo_limit = (size_t)(_max_old_gen_size - _avg_old_live);
343 // But don't force a promo size below the current promo size. Otherwise,
344 // the promo size will shrink for no good reason.
345 promo_limit = MAX2(promo_limit, _promo_size);
346
347 log_trace(gc, ergo)(
348 "AdaptiveSizePolicySpaceOverheadTester::is_exceeded:"
349 " promo_limit: " SIZE_FORMAT
350 " max_eden_size: " SIZE_FORMAT
351 " total_free_limit: " SIZE_FORMAT
352 " max_old_gen_size: " SIZE_FORMAT
353 " max_eden_size: " SIZE_FORMAT
354 " mem_free_limit: " SIZE_FORMAT,
355 promo_limit, _max_eden_size, total_free_limit,
356 _max_old_gen_size, _max_eden_size,
357 (size_t)mem_free_limit);
358
359 return free_in_old_gen < (size_t)mem_free_old_limit &&
360 free_in_eden < (size_t)mem_free_eden_limit;
361 }
362
363 };
364
365 void AdaptiveSizePolicy::check_gc_overhead_limit(
366 size_t eden_live,
367 size_t max_old_gen_size,
368 size_t max_eden_size,
369 bool is_full_gc,
370 GCCause::Cause gc_cause,
371 SoftRefPolicy* soft_ref_policy) {
372
373 AdaptiveSizePolicyTimeOverheadTester time_overhead(gc_cost());
374 AdaptiveSizePolicySpaceOverheadTester space_overhead(eden_live,
375 max_old_gen_size,
376 max_eden_size,
377 _promo_size,
378 avg_eden_live()->average(),
379 avg_old_live()->average());
380 _overhead_checker.check_gc_overhead_limit(&time_overhead,
381 &space_overhead,
382 is_full_gc,
|
36 // _throughput_goal = 1 - ( 1 / (1 + gc_cost_ratio))
37 // gc_cost_ratio is the ratio
38 // application cost / gc cost
39 // For example a gc_cost_ratio of 4 translates into a
40 // throughput goal of .80
41
42 AdaptiveSizePolicy::AdaptiveSizePolicy(size_t init_eden_size,
43 size_t init_promo_size,
44 size_t init_survivor_size,
45 double gc_pause_goal_sec,
46 uint gc_cost_ratio) :
47 _throughput_goal(1.0 - double(1.0 / (1.0 + (double) gc_cost_ratio))),
48 _eden_size(init_eden_size),
49 _promo_size(init_promo_size),
50 _survivor_size(init_survivor_size),
51 _latest_minor_mutator_interval_seconds(0),
52 _threshold_tolerance_percent(1.0 + ThresholdTolerance/100.0),
53 _gc_pause_goal_sec(gc_pause_goal_sec),
54 _young_gen_change_for_minor_throughput(0),
55 _old_gen_change_for_major_throughput(0) {
56 _avg_minor_pause =
57 new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding);
58 _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
59 _avg_minor_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
60 _avg_major_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
61
62 _avg_young_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
63 _avg_old_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
64 _avg_eden_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
65
66 _avg_survived = new AdaptivePaddedAverage(AdaptiveSizePolicyWeight,
67 SurvivorPadding);
68 _avg_pretenured = new AdaptivePaddedNoZeroDevAverage(
69 AdaptiveSizePolicyWeight,
70 SurvivorPadding);
71
72 _minor_pause_old_estimator =
73 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
74 _minor_pause_young_estimator =
75 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
254 avg_major_interval, time_since_last_major_gc);
255 log_trace(gc, ergo)(" major gc cost: %f decayed major gc cost: %f",
256 major_gc_cost(), decayed_major_gc_cost);
257 }
258 }
259 double result = MIN2(1.0, decayed_major_gc_cost + minor_gc_cost());
260 return result;
261 }
262
263
264 void AdaptiveSizePolicy::clear_generation_free_space_flags() {
265 set_change_young_gen_for_min_pauses(0);
266 set_change_old_gen_for_maj_pauses(0);
267
268 set_change_old_gen_for_throughput(0);
269 set_change_young_gen_for_throughput(0);
270 set_decrease_for_footprint(0);
271 set_decide_at_full_gc(0);
272 }
273
274 class AdaptiveSizePolicyTimeOverheadTester: public GCOverheadTester {
275 double _gc_cost;
276
277 public:
278 AdaptiveSizePolicyTimeOverheadTester(double gc_cost) : _gc_cost(gc_cost) {}
279
280 bool is_exceeded() {
281 // Note that the gc time limit test only works for the collections
282 // of the young gen + tenured gen and not for collections of the
283 // permanent gen. That is because the calculation of the space
284 // freed by the collection is the free space in the young gen +
285 // tenured gen.
286 return _gc_cost > (GCTimeLimit / 100.0);
287 }
288 };
289
290 class AdaptiveSizePolicySpaceOverheadTester: public GCOverheadTester {
291 size_t _eden_live;
292 size_t _max_old_gen_size;
293 size_t _max_eden_size;
294 size_t _promo_size;
295 double _avg_eden_live;
296 double _avg_old_live;
297
298 public:
299 AdaptiveSizePolicySpaceOverheadTester(size_t eden_live,
300 size_t max_old_gen_size,
301 size_t max_eden_size,
302 size_t promo_size,
303 double avg_eden_live,
304 double avg_old_live) :
305 _eden_live(eden_live),
306 _max_old_gen_size(max_old_gen_size),
307 _max_eden_size(max_eden_size),
308 _promo_size(promo_size),
309 _avg_eden_live(avg_eden_live),
310 _avg_old_live(avg_old_live) {}
340 size_t promo_limit = (size_t)(_max_old_gen_size - _avg_old_live);
341 // But don't force a promo size below the current promo size. Otherwise,
342 // the promo size will shrink for no good reason.
343 promo_limit = MAX2(promo_limit, _promo_size);
344
345 log_trace(gc, ergo)(
346 "AdaptiveSizePolicySpaceOverheadTester::is_exceeded:"
347 " promo_limit: " SIZE_FORMAT
348 " max_eden_size: " SIZE_FORMAT
349 " total_free_limit: " SIZE_FORMAT
350 " max_old_gen_size: " SIZE_FORMAT
351 " max_eden_size: " SIZE_FORMAT
352 " mem_free_limit: " SIZE_FORMAT,
353 promo_limit, _max_eden_size, total_free_limit,
354 _max_old_gen_size, _max_eden_size,
355 (size_t)mem_free_limit);
356
357 return free_in_old_gen < (size_t)mem_free_old_limit &&
358 free_in_eden < (size_t)mem_free_eden_limit;
359 }
360 };
361
362 void AdaptiveSizePolicy::check_gc_overhead_limit(
363 size_t eden_live,
364 size_t max_old_gen_size,
365 size_t max_eden_size,
366 bool is_full_gc,
367 GCCause::Cause gc_cause,
368 SoftRefPolicy* soft_ref_policy) {
369
370 AdaptiveSizePolicyTimeOverheadTester time_overhead(gc_cost());
371 AdaptiveSizePolicySpaceOverheadTester space_overhead(eden_live,
372 max_old_gen_size,
373 max_eden_size,
374 _promo_size,
375 avg_eden_live()->average(),
376 avg_old_live()->average());
377 _overhead_checker.check_gc_overhead_limit(&time_overhead,
378 &space_overhead,
379 is_full_gc,
|