Thu, 14 Mar 2013 09:37:38 +0100
6733980: par compact - TraceGen1Time always shows 0.0000 seconds
Summary: Use the correct collector to retrieve accumulated gen1 trace time
Reviewed-by: johnc, jmasa
1 /*
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #include "precompiled.hpp"
26 #include "gc_implementation/parallelScavenge/generationSizer.hpp"
27 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
28 #include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
29 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
30 #include "gc_implementation/shared/gcPolicyCounters.hpp"
31 #include "gc_interface/gcCause.hpp"
32 #include "memory/collectorPolicy.hpp"
33 #include "runtime/timer.hpp"
34 #include "utilities/top.hpp"
36 #include <math.h>
38 PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
39 size_t init_promo_size,
40 size_t init_survivor_size,
41 size_t intra_generation_alignment,
42 double gc_pause_goal_sec,
43 double gc_minor_pause_goal_sec,
44 uint gc_cost_ratio) :
45 AdaptiveSizePolicy(init_eden_size,
46 init_promo_size,
47 init_survivor_size,
48 gc_pause_goal_sec,
49 gc_cost_ratio),
50 _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin/
51 100.0),
52 _intra_generation_alignment(intra_generation_alignment),
53 _live_at_last_full_gc(init_promo_size),
54 _gc_minor_pause_goal_sec(gc_minor_pause_goal_sec),
55 _latest_major_mutator_interval_seconds(0),
56 _young_gen_change_for_major_pause_count(0)
57 {
58 // Sizing policy statistics
59 _avg_major_pause =
60 new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding);
61 _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
62 _avg_major_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
64 _avg_base_footprint = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
65 _major_pause_old_estimator =
66 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
67 _major_pause_young_estimator =
68 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
69 _major_collection_estimator =
70 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
72 _young_gen_size_increment_supplement = YoungGenerationSizeSupplement;
73 _old_gen_size_increment_supplement = TenuredGenerationSizeSupplement;
75 // Start the timers
76 _major_timer.start();
78 _old_gen_policy_is_ready = false;
79 }
81 void PSAdaptiveSizePolicy::major_collection_begin() {
82 // Update the interval time
83 _major_timer.stop();
84 // Save most recent collection time
85 _latest_major_mutator_interval_seconds = _major_timer.seconds();
86 _major_timer.reset();
87 _major_timer.start();
88 }
90 void PSAdaptiveSizePolicy::update_minor_pause_old_estimator(
91 double minor_pause_in_ms) {
92 double promo_size_in_mbytes = ((double)_promo_size)/((double)M);
93 _minor_pause_old_estimator->update(promo_size_in_mbytes,
94 minor_pause_in_ms);
95 }
97 void PSAdaptiveSizePolicy::major_collection_end(size_t amount_live,
98 GCCause::Cause gc_cause) {
99 // Update the pause time.
100 _major_timer.stop();
102 if (gc_cause != GCCause::_java_lang_system_gc ||
103 UseAdaptiveSizePolicyWithSystemGC) {
104 double major_pause_in_seconds = _major_timer.seconds();
105 double major_pause_in_ms = major_pause_in_seconds * MILLIUNITS;
107 // Sample for performance counter
108 _avg_major_pause->sample(major_pause_in_seconds);
110 // Cost of collection (unit-less)
111 double collection_cost = 0.0;
112 if ((_latest_major_mutator_interval_seconds > 0.0) &&
113 (major_pause_in_seconds > 0.0)) {
114 double interval_in_seconds =
115 _latest_major_mutator_interval_seconds + major_pause_in_seconds;
116 collection_cost =
117 major_pause_in_seconds / interval_in_seconds;
118 avg_major_gc_cost()->sample(collection_cost);
120 // Sample for performance counter
121 _avg_major_interval->sample(interval_in_seconds);
122 }
124 // Calculate variables used to estimate pause time vs. gen sizes
125 double eden_size_in_mbytes = ((double)_eden_size)/((double)M);
126 double promo_size_in_mbytes = ((double)_promo_size)/((double)M);
127 _major_pause_old_estimator->update(promo_size_in_mbytes,
128 major_pause_in_ms);
129 _major_pause_young_estimator->update(eden_size_in_mbytes,
130 major_pause_in_ms);
132 if (PrintAdaptiveSizePolicy && Verbose) {
133 gclog_or_tty->print("psAdaptiveSizePolicy::major_collection_end: "
134 "major gc cost: %f average: %f", collection_cost,
135 avg_major_gc_cost()->average());
136 gclog_or_tty->print_cr(" major pause: %f major period %f",
137 major_pause_in_ms,
138 _latest_major_mutator_interval_seconds * MILLIUNITS);
139 }
141 // Calculate variable used to estimate collection cost vs. gen sizes
142 assert(collection_cost >= 0.0, "Expected to be non-negative");
143 _major_collection_estimator->update(promo_size_in_mbytes,
144 collection_cost);
145 }
147 // Update the amount live at the end of a full GC
148 _live_at_last_full_gc = amount_live;
150 // The policy does not have enough data until at least some major collections
151 // have been done.
152 if (_avg_major_pause->count() >= AdaptiveSizePolicyReadyThreshold) {
153 _old_gen_policy_is_ready = true;
154 }
156 // Interval times use this timer to measure the interval that
157 // the mutator runs. Reset after the GC pause has been measured.
158 _major_timer.reset();
159 _major_timer.start();
160 }
162 // If the remaining free space in the old generation is less that
163 // that expected to be needed by the next collection, do a full
164 // collection now.
165 bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) {
167 // A similar test is done in the scavenge's should_attempt_scavenge(). If
168 // this is changed, decide if that test should also be changed.
169 bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes;
170 if (PrintGCDetails && Verbose) {
171 if (result) {
172 gclog_or_tty->print(" full after scavenge: ");
173 } else {
174 gclog_or_tty->print(" no full after scavenge: ");
175 }
176 gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
177 " padded_average_promoted " SIZE_FORMAT
178 " free in old gen " SIZE_FORMAT,
179 (size_t) average_promoted_in_bytes(),
180 (size_t) padded_average_promoted_in_bytes(),
181 old_free_in_bytes);
182 }
183 return result;
184 }
186 void PSAdaptiveSizePolicy::clear_generation_free_space_flags() {
188 AdaptiveSizePolicy::clear_generation_free_space_flags();
190 set_change_old_gen_for_min_pauses(0);
192 set_change_young_gen_for_maj_pauses(0);
193 }
195 // If this is not a full GC, only test and modify the young generation.
197 void PSAdaptiveSizePolicy::compute_generation_free_space(
198 size_t young_live,
199 size_t eden_live,
200 size_t old_live,
201 size_t cur_eden,
202 size_t max_old_gen_size,
203 size_t max_eden_size,
204 bool is_full_gc,
205 GCCause::Cause gc_cause,
206 CollectorPolicy* collector_policy) {
208 // Update statistics
209 // Time statistics are updated as we go, update footprint stats here
210 _avg_base_footprint->sample(BaseFootPrintEstimate);
211 avg_young_live()->sample(young_live);
212 avg_eden_live()->sample(eden_live);
213 if (is_full_gc) {
214 // old_live is only accurate after a full gc
215 avg_old_live()->sample(old_live);
216 }
218 // This code used to return if the policy was not ready , i.e.,
219 // policy_is_ready() returning false. The intent was that
220 // decisions below needed major collection times and so could
221 // not be made before two major collections. A consequence was
222 // adjustments to the young generation were not done until after
223 // two major collections even if the minor collections times
224 // exceeded the requested goals. Now let the young generation
225 // adjust for the minor collection times. Major collection times
226 // will be zero for the first collection and will naturally be
227 // ignored. Tenured generation adjustments are only made at the
228 // full collections so until the second major collection has
229 // been reached, no tenured generation adjustments will be made.
231 // Until we know better, desired promotion size uses the last calculation
232 size_t desired_promo_size = _promo_size;
234 // Start eden at the current value. The desired value that is stored
235 // in _eden_size is not bounded by constraints of the heap and can
236 // run away.
237 //
238 // As expected setting desired_eden_size to the current
239 // value of desired_eden_size as a starting point
240 // caused desired_eden_size to grow way too large and caused
241 // an overflow down stream. It may have improved performance in
242 // some case but is dangerous.
243 size_t desired_eden_size = cur_eden;
245 #ifdef ASSERT
246 size_t original_promo_size = desired_promo_size;
247 size_t original_eden_size = desired_eden_size;
248 #endif
250 // Cache some values. There's a bit of work getting these, so
251 // we might save a little time.
252 const double major_cost = major_gc_cost();
253 const double minor_cost = minor_gc_cost();
255 // Used for diagnostics
256 clear_generation_free_space_flags();
258 // Limits on our growth
259 size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average());
261 // This method sets the desired eden size. That plus the
262 // desired survivor space sizes sets the desired young generation
263 // size. This methods does not know what the desired survivor
264 // size is but expects that other policy will attempt to make
265 // the survivor sizes compatible with the live data in the
266 // young generation. This limit is an estimate of the space left
267 // in the young generation after the survivor spaces have been
268 // subtracted out.
269 size_t eden_limit = max_eden_size;
271 // But don't force a promo size below the current promo size. Otherwise,
272 // the promo size will shrink for no good reason.
273 promo_limit = MAX2(promo_limit, _promo_size);
275 const double gc_cost_limit = GCTimeLimit/100.0;
277 // Which way should we go?
278 // if pause requirement is not met
279 // adjust size of any generation with average paus exceeding
280 // the pause limit. Adjust one pause at a time (the larger)
281 // and only make adjustments for the major pause at full collections.
282 // else if throughput requirement not met
283 // adjust the size of the generation with larger gc time. Only
284 // adjust one generation at a time.
285 // else
286 // adjust down the total heap size. Adjust down the larger of the
287 // generations.
289 // Add some checks for a threshhold for a change. For example,
290 // a change less than the necessary alignment is probably not worth
291 // attempting.
294 if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) ||
295 (_avg_major_pause->padded_average() > gc_pause_goal_sec())) {
296 //
297 // Check pauses
298 //
299 // Make changes only to affect one of the pauses (the larger)
300 // at a time.
301 adjust_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
303 } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
304 // Adjust only for the minor pause time goal
305 adjust_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
307 } else if(adjusted_mutator_cost() < _throughput_goal) {
308 // This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
309 // This sometimes resulted in skipping to the minimize footprint
310 // code. Change this to try and reduce GC time if mutator time is
311 // negative for whatever reason. Or for future consideration,
312 // bail out of the code if mutator time is negative.
313 //
314 // Throughput
315 //
316 assert(major_cost >= 0.0, "major cost is < 0.0");
317 assert(minor_cost >= 0.0, "minor cost is < 0.0");
318 // Try to reduce the GC times.
319 adjust_for_throughput(is_full_gc, &desired_promo_size, &desired_eden_size);
321 } else {
323 // Be conservative about reducing the footprint.
324 // Do a minimum number of major collections first.
325 // Have reasonable averages for major and minor collections costs.
326 if (UseAdaptiveSizePolicyFootprintGoal &&
327 young_gen_policy_is_ready() &&
328 avg_major_gc_cost()->average() >= 0.0 &&
329 avg_minor_gc_cost()->average() >= 0.0) {
330 size_t desired_sum = desired_eden_size + desired_promo_size;
331 desired_eden_size = adjust_eden_for_footprint(desired_eden_size,
332 desired_sum);
333 if (is_full_gc) {
334 set_decide_at_full_gc(decide_at_full_gc_true);
335 desired_promo_size = adjust_promo_for_footprint(desired_promo_size,
336 desired_sum);
337 }
338 }
339 }
341 // Note we make the same tests as in the code block below; the code
342 // seems a little easier to read with the printing in another block.
343 if (PrintAdaptiveSizePolicy) {
344 if (desired_promo_size > promo_limit) {
345 // "free_in_old_gen" was the original value for used for promo_limit
346 size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
347 gclog_or_tty->print_cr(
348 "PSAdaptiveSizePolicy::compute_generation_free_space limits:"
349 " desired_promo_size: " SIZE_FORMAT
350 " promo_limit: " SIZE_FORMAT
351 " free_in_old_gen: " SIZE_FORMAT
352 " max_old_gen_size: " SIZE_FORMAT
353 " avg_old_live: " SIZE_FORMAT,
354 desired_promo_size, promo_limit, free_in_old_gen,
355 max_old_gen_size, (size_t) avg_old_live()->average());
356 }
357 if (desired_eden_size > eden_limit) {
358 gclog_or_tty->print_cr(
359 "AdaptiveSizePolicy::compute_generation_free_space limits:"
360 " desired_eden_size: " SIZE_FORMAT
361 " old_eden_size: " SIZE_FORMAT
362 " eden_limit: " SIZE_FORMAT
363 " cur_eden: " SIZE_FORMAT
364 " max_eden_size: " SIZE_FORMAT
365 " avg_young_live: " SIZE_FORMAT,
366 desired_eden_size, _eden_size, eden_limit, cur_eden,
367 max_eden_size, (size_t)avg_young_live()->average());
368 }
369 if (gc_cost() > gc_cost_limit) {
370 gclog_or_tty->print_cr(
371 "AdaptiveSizePolicy::compute_generation_free_space: gc time limit"
372 " gc_cost: %f "
373 " GCTimeLimit: %d",
374 gc_cost(), GCTimeLimit);
375 }
376 }
378 // Align everything and make a final limit check
379 const size_t alignment = _intra_generation_alignment;
380 desired_eden_size = align_size_up(desired_eden_size, alignment);
381 desired_eden_size = MAX2(desired_eden_size, alignment);
382 desired_promo_size = align_size_up(desired_promo_size, alignment);
383 desired_promo_size = MAX2(desired_promo_size, alignment);
385 eden_limit = align_size_down(eden_limit, alignment);
386 promo_limit = align_size_down(promo_limit, alignment);
388 // Is too much time being spent in GC?
389 // Is the heap trying to grow beyond it's limits?
391 const size_t free_in_old_gen =
392 (size_t)(max_old_gen_size - avg_old_live()->average());
393 if (desired_promo_size > free_in_old_gen && desired_eden_size > eden_limit) {
394 check_gc_overhead_limit(young_live,
395 eden_live,
396 max_old_gen_size,
397 max_eden_size,
398 is_full_gc,
399 gc_cause,
400 collector_policy);
401 }
404 // And one last limit check, now that we've aligned things.
405 if (desired_eden_size > eden_limit) {
406 // If the policy says to get a larger eden but
407 // is hitting the limit, don't decrease eden.
408 // This can lead to a general drifting down of the
409 // eden size. Let the tenuring calculation push more
410 // into the old gen.
411 desired_eden_size = MAX2(eden_limit, cur_eden);
412 }
413 desired_promo_size = MIN2(desired_promo_size, promo_limit);
416 if (PrintAdaptiveSizePolicy) {
417 // Timing stats
418 gclog_or_tty->print(
419 "PSAdaptiveSizePolicy::compute_generation_free_space: costs"
420 " minor_time: %f"
421 " major_cost: %f"
422 " mutator_cost: %f"
423 " throughput_goal: %f",
424 minor_gc_cost(), major_gc_cost(), mutator_cost(),
425 _throughput_goal);
427 // We give more details if Verbose is set
428 if (Verbose) {
429 gclog_or_tty->print( " minor_pause: %f"
430 " major_pause: %f"
431 " minor_interval: %f"
432 " major_interval: %f"
433 " pause_goal: %f",
434 _avg_minor_pause->padded_average(),
435 _avg_major_pause->padded_average(),
436 _avg_minor_interval->average(),
437 _avg_major_interval->average(),
438 gc_pause_goal_sec());
439 }
441 // Footprint stats
442 gclog_or_tty->print( " live_space: " SIZE_FORMAT
443 " free_space: " SIZE_FORMAT,
444 live_space(), free_space());
445 // More detail
446 if (Verbose) {
447 gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
448 " avg_young_live: " SIZE_FORMAT
449 " avg_old_live: " SIZE_FORMAT,
450 (size_t)_avg_base_footprint->average(),
451 (size_t)avg_young_live()->average(),
452 (size_t)avg_old_live()->average());
453 }
455 // And finally, our old and new sizes.
456 gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT
457 " old_eden_size: " SIZE_FORMAT
458 " desired_promo_size: " SIZE_FORMAT
459 " desired_eden_size: " SIZE_FORMAT,
460 _promo_size, _eden_size,
461 desired_promo_size, desired_eden_size);
462 gclog_or_tty->cr();
463 }
465 decay_supplemental_growth(is_full_gc);
467 set_promo_size(desired_promo_size);
468 set_eden_size(desired_eden_size);
469 };
471 void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) {
472 // Decay the supplemental increment? Decay the supplement growth
473 // factor even if it is not used. It is only meant to give a boost
474 // to the initial growth and if it is not used, then it was not
475 // needed.
476 if (is_full_gc) {
477 // Don't wait for the threshold value for the major collections. If
478 // here, the supplemental growth term was used and should decay.
479 if ((_avg_major_pause->count() % TenuredGenerationSizeSupplementDecay)
480 == 0) {
481 _old_gen_size_increment_supplement =
482 _old_gen_size_increment_supplement >> 1;
483 }
484 } else {
485 if ((_avg_minor_pause->count() >= AdaptiveSizePolicyReadyThreshold) &&
486 (_avg_minor_pause->count() % YoungGenerationSizeSupplementDecay) == 0) {
487 _young_gen_size_increment_supplement =
488 _young_gen_size_increment_supplement >> 1;
489 }
490 }
491 }
493 void PSAdaptiveSizePolicy::adjust_for_minor_pause_time(bool is_full_gc,
494 size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr) {
496 // Adjust the young generation size to reduce pause time of
497 // of collections.
498 //
499 // The AdaptiveSizePolicyInitializingSteps test is not used
500 // here. It has not seemed to be needed but perhaps should
501 // be added for consistency.
502 if (minor_pause_young_estimator()->decrement_will_decrease()) {
503 // reduce eden size
504 set_change_young_gen_for_min_pauses(
505 decrease_young_gen_for_min_pauses_true);
506 *desired_eden_size_ptr = *desired_eden_size_ptr -
507 eden_decrement_aligned_down(*desired_eden_size_ptr);
508 } else {
509 // EXPERIMENTAL ADJUSTMENT
510 // Only record that the estimator indicated such an action.
511 // *desired_eden_size_ptr = *desired_eden_size_ptr + eden_heap_delta;
512 set_change_young_gen_for_min_pauses(
513 increase_young_gen_for_min_pauses_true);
514 }
515 if (PSAdjustTenuredGenForMinorPause) {
516 // If the desired eden size is as small as it will get,
517 // try to adjust the old gen size.
518 if (*desired_eden_size_ptr <= _intra_generation_alignment) {
519 // Vary the old gen size to reduce the young gen pause. This
520 // may not be a good idea. This is just a test.
521 if (minor_pause_old_estimator()->decrement_will_decrease()) {
522 set_change_old_gen_for_min_pauses(
523 decrease_old_gen_for_min_pauses_true);
524 *desired_promo_size_ptr =
525 _promo_size - promo_decrement_aligned_down(*desired_promo_size_ptr);
526 } else {
527 set_change_old_gen_for_min_pauses(
528 increase_old_gen_for_min_pauses_true);
529 size_t promo_heap_delta =
530 promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
531 if ((*desired_promo_size_ptr + promo_heap_delta) >
532 *desired_promo_size_ptr) {
533 *desired_promo_size_ptr =
534 _promo_size + promo_heap_delta;
535 }
536 }
537 }
538 }
539 }
541 void PSAdaptiveSizePolicy::adjust_for_pause_time(bool is_full_gc,
542 size_t* desired_promo_size_ptr,
543 size_t* desired_eden_size_ptr) {
545 size_t promo_heap_delta = 0;
546 size_t eden_heap_delta = 0;
547 // Add some checks for a threshhold for a change. For example,
548 // a change less than the required alignment is probably not worth
549 // attempting.
550 if (is_full_gc) {
551 set_decide_at_full_gc(decide_at_full_gc_true);
552 }
554 if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
555 adjust_for_minor_pause_time(is_full_gc,
556 desired_promo_size_ptr,
557 desired_eden_size_ptr);
558 // major pause adjustments
559 } else if (is_full_gc) {
560 // Adjust for the major pause time only at full gc's because the
561 // affects of a change can only be seen at full gc's.
563 // Reduce old generation size to reduce pause?
564 if (major_pause_old_estimator()->decrement_will_decrease()) {
565 // reduce old generation size
566 set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true);
567 promo_heap_delta = promo_decrement_aligned_down(*desired_promo_size_ptr);
568 *desired_promo_size_ptr = _promo_size - promo_heap_delta;
569 } else {
570 // EXPERIMENTAL ADJUSTMENT
571 // Only record that the estimator indicated such an action.
572 // *desired_promo_size_ptr = _promo_size +
573 // promo_increment_aligned_up(*desired_promo_size_ptr);
574 set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true);
575 }
576 if (PSAdjustYoungGenForMajorPause) {
577 // If the promo size is at the minimum (i.e., the old gen
578 // size will not actually decrease), consider changing the
579 // young gen size.
580 if (*desired_promo_size_ptr < _intra_generation_alignment) {
581 // If increasing the young generation will decrease the old gen
582 // pause, do it.
583 // During startup there is noise in the statistics for deciding
584 // on whether to increase or decrease the young gen size. For
585 // some number of iterations, just try to increase the young
586 // gen size if the major pause is too long to try and establish
587 // good statistics for later decisions.
588 if (major_pause_young_estimator()->increment_will_decrease() ||
589 (_young_gen_change_for_major_pause_count
590 <= AdaptiveSizePolicyInitializingSteps)) {
591 set_change_young_gen_for_maj_pauses(
592 increase_young_gen_for_maj_pauses_true);
593 eden_heap_delta = eden_increment_aligned_up(*desired_eden_size_ptr);
594 *desired_eden_size_ptr = _eden_size + eden_heap_delta;
595 _young_gen_change_for_major_pause_count++;
596 } else {
597 // Record that decreasing the young gen size would decrease
598 // the major pause
599 set_change_young_gen_for_maj_pauses(
600 decrease_young_gen_for_maj_pauses_true);
601 eden_heap_delta = eden_decrement_aligned_down(*desired_eden_size_ptr);
602 *desired_eden_size_ptr = _eden_size - eden_heap_delta;
603 }
604 }
605 }
606 }
608 if (PrintAdaptiveSizePolicy && Verbose) {
609 gclog_or_tty->print_cr(
610 "AdaptiveSizePolicy::compute_generation_free_space "
611 "adjusting gen sizes for major pause (avg %f goal %f). "
612 "desired_promo_size " SIZE_FORMAT "desired_eden_size "
613 SIZE_FORMAT
614 " promo delta " SIZE_FORMAT " eden delta " SIZE_FORMAT,
615 _avg_major_pause->average(), gc_pause_goal_sec(),
616 *desired_promo_size_ptr, *desired_eden_size_ptr,
617 promo_heap_delta, eden_heap_delta);
618 }
619 }
621 void PSAdaptiveSizePolicy::adjust_for_throughput(bool is_full_gc,
622 size_t* desired_promo_size_ptr,
623 size_t* desired_eden_size_ptr) {
625 // Add some checks for a threshhold for a change. For example,
626 // a change less than the required alignment is probably not worth
627 // attempting.
628 if (is_full_gc) {
629 set_decide_at_full_gc(decide_at_full_gc_true);
630 }
632 if ((gc_cost() + mutator_cost()) == 0.0) {
633 return;
634 }
636 if (PrintAdaptiveSizePolicy && Verbose) {
637 gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_for_throughput("
638 "is_full: %d, promo: " SIZE_FORMAT ", cur_eden: " SIZE_FORMAT "): ",
639 is_full_gc, *desired_promo_size_ptr, *desired_eden_size_ptr);
640 gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f "
641 "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
642 }
644 // Tenured generation
645 if (is_full_gc) {
647 // Calculate the change to use for the tenured gen.
648 size_t scaled_promo_heap_delta = 0;
649 // Can the increment to the generation be scaled?
650 if (gc_cost() >= 0.0 && major_gc_cost() >= 0.0) {
651 size_t promo_heap_delta =
652 promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
653 double scale_by_ratio = major_gc_cost() / gc_cost();
654 scaled_promo_heap_delta =
655 (size_t) (scale_by_ratio * (double) promo_heap_delta);
656 if (PrintAdaptiveSizePolicy && Verbose) {
657 gclog_or_tty->print_cr(
658 "Scaled tenured increment: " SIZE_FORMAT " by %f down to "
659 SIZE_FORMAT,
660 promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
661 }
662 } else if (major_gc_cost() >= 0.0) {
663 // Scaling is not going to work. If the major gc time is the
664 // larger, give it a full increment.
665 if (major_gc_cost() >= minor_gc_cost()) {
666 scaled_promo_heap_delta =
667 promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
668 }
669 } else {
670 // Don't expect to get here but it's ok if it does
671 // in the product build since the delta will be 0
672 // and nothing will change.
673 assert(false, "Unexpected value for gc costs");
674 }
676 switch (AdaptiveSizeThroughPutPolicy) {
677 case 1:
678 // Early in the run the statistics might not be good. Until
679 // a specific number of collections have been, use the heuristic
680 // that a larger generation size means lower collection costs.
681 if (major_collection_estimator()->increment_will_decrease() ||
682 (_old_gen_change_for_major_throughput
683 <= AdaptiveSizePolicyInitializingSteps)) {
684 // Increase tenured generation size to reduce major collection cost
685 if ((*desired_promo_size_ptr + scaled_promo_heap_delta) >
686 *desired_promo_size_ptr) {
687 *desired_promo_size_ptr = _promo_size + scaled_promo_heap_delta;
688 }
689 set_change_old_gen_for_throughput(
690 increase_old_gen_for_throughput_true);
691 _old_gen_change_for_major_throughput++;
692 } else {
693 // EXPERIMENTAL ADJUSTMENT
694 // Record that decreasing the old gen size would decrease
695 // the major collection cost but don't do it.
696 // *desired_promo_size_ptr = _promo_size -
697 // promo_decrement_aligned_down(*desired_promo_size_ptr);
698 set_change_old_gen_for_throughput(
699 decrease_old_gen_for_throughput_true);
700 }
702 break;
703 default:
704 // Simplest strategy
705 if ((*desired_promo_size_ptr + scaled_promo_heap_delta) >
706 *desired_promo_size_ptr) {
707 *desired_promo_size_ptr = *desired_promo_size_ptr +
708 scaled_promo_heap_delta;
709 }
710 set_change_old_gen_for_throughput(
711 increase_old_gen_for_throughput_true);
712 _old_gen_change_for_major_throughput++;
713 }
715 if (PrintAdaptiveSizePolicy && Verbose) {
716 gclog_or_tty->print_cr(
717 "adjusting tenured gen for throughput (avg %f goal %f). "
718 "desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT ,
719 mutator_cost(), _throughput_goal,
720 *desired_promo_size_ptr, scaled_promo_heap_delta);
721 }
722 }
724 // Young generation
725 size_t scaled_eden_heap_delta = 0;
726 // Can the increment to the generation be scaled?
727 if (gc_cost() >= 0.0 && minor_gc_cost() >= 0.0) {
728 size_t eden_heap_delta =
729 eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
730 double scale_by_ratio = minor_gc_cost() / gc_cost();
731 assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong");
732 scaled_eden_heap_delta =
733 (size_t) (scale_by_ratio * (double) eden_heap_delta);
734 if (PrintAdaptiveSizePolicy && Verbose) {
735 gclog_or_tty->print_cr(
736 "Scaled eden increment: " SIZE_FORMAT " by %f down to "
737 SIZE_FORMAT,
738 eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
739 }
740 } else if (minor_gc_cost() >= 0.0) {
741 // Scaling is not going to work. If the minor gc time is the
742 // larger, give it a full increment.
743 if (minor_gc_cost() > major_gc_cost()) {
744 scaled_eden_heap_delta =
745 eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
746 }
747 } else {
748 // Don't expect to get here but it's ok if it does
749 // in the product build since the delta will be 0
750 // and nothing will change.
751 assert(false, "Unexpected value for gc costs");
752 }
754 // Use a heuristic for some number of collections to give
755 // the averages time to settle down.
756 switch (AdaptiveSizeThroughPutPolicy) {
757 case 1:
758 if (minor_collection_estimator()->increment_will_decrease() ||
759 (_young_gen_change_for_minor_throughput
760 <= AdaptiveSizePolicyInitializingSteps)) {
761 // Expand young generation size to reduce frequency of
762 // of collections.
763 if ((*desired_eden_size_ptr + scaled_eden_heap_delta) >
764 *desired_eden_size_ptr) {
765 *desired_eden_size_ptr =
766 *desired_eden_size_ptr + scaled_eden_heap_delta;
767 }
768 set_change_young_gen_for_throughput(
769 increase_young_gen_for_througput_true);
770 _young_gen_change_for_minor_throughput++;
771 } else {
772 // EXPERIMENTAL ADJUSTMENT
773 // Record that decreasing the young gen size would decrease
774 // the minor collection cost but don't do it.
775 // *desired_eden_size_ptr = _eden_size -
776 // eden_decrement_aligned_down(*desired_eden_size_ptr);
777 set_change_young_gen_for_throughput(
778 decrease_young_gen_for_througput_true);
779 }
780 break;
781 default:
782 if ((*desired_eden_size_ptr + scaled_eden_heap_delta) >
783 *desired_eden_size_ptr) {
784 *desired_eden_size_ptr =
785 *desired_eden_size_ptr + scaled_eden_heap_delta;
786 }
787 set_change_young_gen_for_throughput(
788 increase_young_gen_for_througput_true);
789 _young_gen_change_for_minor_throughput++;
790 }
792 if (PrintAdaptiveSizePolicy && Verbose) {
793 gclog_or_tty->print_cr(
794 "adjusting eden for throughput (avg %f goal %f). desired_eden_size "
795 SIZE_FORMAT " eden delta " SIZE_FORMAT "\n",
796 mutator_cost(), _throughput_goal,
797 *desired_eden_size_ptr, scaled_eden_heap_delta);
798 }
799 }
801 size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
802 size_t desired_promo_size, size_t desired_sum) {
803 assert(desired_promo_size <= desired_sum, "Inconsistent parameters");
804 set_decrease_for_footprint(decrease_old_gen_for_footprint_true);
806 size_t change = promo_decrement(desired_promo_size);
807 change = scale_down(change, desired_promo_size, desired_sum);
809 size_t reduced_size = desired_promo_size - change;
811 if (PrintAdaptiveSizePolicy && Verbose) {
812 gclog_or_tty->print_cr(
813 "AdaptiveSizePolicy::compute_generation_free_space "
814 "adjusting tenured gen for footprint. "
815 "starting promo size " SIZE_FORMAT
816 " reduced promo size " SIZE_FORMAT,
817 " promo delta " SIZE_FORMAT,
818 desired_promo_size, reduced_size, change );
819 }
821 assert(reduced_size <= desired_promo_size, "Inconsistent result");
822 return reduced_size;
823 }
825 size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint(
826 size_t desired_eden_size, size_t desired_sum) {
827 assert(desired_eden_size <= desired_sum, "Inconsistent parameters");
828 set_decrease_for_footprint(decrease_young_gen_for_footprint_true);
830 size_t change = eden_decrement(desired_eden_size);
831 change = scale_down(change, desired_eden_size, desired_sum);
833 size_t reduced_size = desired_eden_size - change;
835 if (PrintAdaptiveSizePolicy && Verbose) {
836 gclog_or_tty->print_cr(
837 "AdaptiveSizePolicy::compute_generation_free_space "
838 "adjusting eden for footprint. "
839 " starting eden size " SIZE_FORMAT
840 " reduced eden size " SIZE_FORMAT
841 " eden delta " SIZE_FORMAT,
842 desired_eden_size, reduced_size, change);
843 }
845 assert(reduced_size <= desired_eden_size, "Inconsistent result");
846 return reduced_size;
847 }
849 // Scale down "change" by the factor
850 // part / total
851 // Don't align the results.
853 size_t PSAdaptiveSizePolicy::scale_down(size_t change,
854 double part,
855 double total) {
856 assert(part <= total, "Inconsistent input");
857 size_t reduced_change = change;
858 if (total > 0) {
859 double fraction = part / total;
860 reduced_change = (size_t) (fraction * (double) change);
861 }
862 assert(reduced_change <= change, "Inconsistent result");
863 return reduced_change;
864 }
866 size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden,
867 uint percent_change) {
868 size_t eden_heap_delta;
869 eden_heap_delta = cur_eden / 100 * percent_change;
870 return eden_heap_delta;
871 }
873 size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden) {
874 return eden_increment(cur_eden, YoungGenerationSizeIncrement);
875 }
877 size_t PSAdaptiveSizePolicy::eden_increment_aligned_up(size_t cur_eden) {
878 size_t result = eden_increment(cur_eden, YoungGenerationSizeIncrement);
879 return align_size_up(result, _intra_generation_alignment);
880 }
882 size_t PSAdaptiveSizePolicy::eden_increment_aligned_down(size_t cur_eden) {
883 size_t result = eden_increment(cur_eden);
884 return align_size_down(result, _intra_generation_alignment);
885 }
887 size_t PSAdaptiveSizePolicy::eden_increment_with_supplement_aligned_up(
888 size_t cur_eden) {
889 size_t result = eden_increment(cur_eden,
890 YoungGenerationSizeIncrement + _young_gen_size_increment_supplement);
891 return align_size_up(result, _intra_generation_alignment);
892 }
894 size_t PSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) {
895 size_t eden_heap_delta = eden_decrement(cur_eden);
896 return align_size_down(eden_heap_delta, _intra_generation_alignment);
897 }
899 size_t PSAdaptiveSizePolicy::eden_decrement(size_t cur_eden) {
900 size_t eden_heap_delta = eden_increment(cur_eden) /
901 AdaptiveSizeDecrementScaleFactor;
902 return eden_heap_delta;
903 }
905 size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo,
906 uint percent_change) {
907 size_t promo_heap_delta;
908 promo_heap_delta = cur_promo / 100 * percent_change;
909 return promo_heap_delta;
910 }
912 size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo) {
913 return promo_increment(cur_promo, TenuredGenerationSizeIncrement);
914 }
916 size_t PSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) {
917 size_t result = promo_increment(cur_promo, TenuredGenerationSizeIncrement);
918 return align_size_up(result, _intra_generation_alignment);
919 }
921 size_t PSAdaptiveSizePolicy::promo_increment_aligned_down(size_t cur_promo) {
922 size_t result = promo_increment(cur_promo, TenuredGenerationSizeIncrement);
923 return align_size_down(result, _intra_generation_alignment);
924 }
926 size_t PSAdaptiveSizePolicy::promo_increment_with_supplement_aligned_up(
927 size_t cur_promo) {
928 size_t result = promo_increment(cur_promo,
929 TenuredGenerationSizeIncrement + _old_gen_size_increment_supplement);
930 return align_size_up(result, _intra_generation_alignment);
931 }
933 size_t PSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) {
934 size_t promo_heap_delta = promo_decrement(cur_promo);
935 return align_size_down(promo_heap_delta, _intra_generation_alignment);
936 }
938 size_t PSAdaptiveSizePolicy::promo_decrement(size_t cur_promo) {
939 size_t promo_heap_delta = promo_increment(cur_promo);
940 promo_heap_delta = promo_heap_delta / AdaptiveSizeDecrementScaleFactor;
941 return promo_heap_delta;
942 }
944 uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
945 bool is_survivor_overflow,
946 uint tenuring_threshold,
947 size_t survivor_limit) {
948 assert(survivor_limit >= _intra_generation_alignment,
949 "survivor_limit too small");
950 assert((size_t)align_size_down(survivor_limit, _intra_generation_alignment)
951 == survivor_limit, "survivor_limit not aligned");
953 // This method is called even if the tenuring threshold and survivor
954 // spaces are not adjusted so that the averages are sampled above.
955 if (!UsePSAdaptiveSurvivorSizePolicy ||
956 !young_gen_policy_is_ready()) {
957 return tenuring_threshold;
958 }
960 // We'll decide whether to increase or decrease the tenuring
961 // threshold based partly on the newly computed survivor size
962 // (if we hit the maximum limit allowed, we'll always choose to
963 // decrement the threshold).
964 bool incr_tenuring_threshold = false;
965 bool decr_tenuring_threshold = false;
967 set_decrement_tenuring_threshold_for_gc_cost(false);
968 set_increment_tenuring_threshold_for_gc_cost(false);
969 set_decrement_tenuring_threshold_for_survivor_limit(false);
971 if (!is_survivor_overflow) {
972 // Keep running averages on how much survived
974 // We use the tenuring threshold to equalize the cost of major
975 // and minor collections.
976 // ThresholdTolerance is used to indicate how sensitive the
977 // tenuring threshold is to differences in cost betweent the
978 // collection types.
980 // Get the times of interest. This involves a little work, so
981 // we cache the values here.
982 const double major_cost = major_gc_cost();
983 const double minor_cost = minor_gc_cost();
985 if (minor_cost > major_cost * _threshold_tolerance_percent) {
986 // Minor times are getting too long; lower the threshold so
987 // less survives and more is promoted.
988 decr_tenuring_threshold = true;
989 set_decrement_tenuring_threshold_for_gc_cost(true);
990 } else if (major_cost > minor_cost * _threshold_tolerance_percent) {
991 // Major times are too long, so we want less promotion.
992 incr_tenuring_threshold = true;
993 set_increment_tenuring_threshold_for_gc_cost(true);
994 }
996 } else {
997 // Survivor space overflow occurred, so promoted and survived are
998 // not accurate. We'll make our best guess by combining survived
999 // and promoted and count them as survivors.
1000 //
1001 // We'll lower the tenuring threshold to see if we can correct
1002 // things. Also, set the survivor size conservatively. We're
1003 // trying to avoid many overflows from occurring if defnew size
1004 // is just too small.
1006 decr_tenuring_threshold = true;
1007 }
1009 // The padded average also maintains a deviation from the average;
1010 // we use this to see how good of an estimate we have of what survived.
1011 // We're trying to pad the survivor size as little as possible without
1012 // overflowing the survivor spaces.
1013 size_t target_size = align_size_up((size_t)_avg_survived->padded_average(),
1014 _intra_generation_alignment);
1015 target_size = MAX2(target_size, _intra_generation_alignment);
1017 if (target_size > survivor_limit) {
1018 // Target size is bigger than we can handle. Let's also reduce
1019 // the tenuring threshold.
1020 target_size = survivor_limit;
1021 decr_tenuring_threshold = true;
1022 set_decrement_tenuring_threshold_for_survivor_limit(true);
1023 }
1025 // Finally, increment or decrement the tenuring threshold, as decided above.
1026 // We test for decrementing first, as we might have hit the target size
1027 // limit.
1028 if (decr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
1029 if (tenuring_threshold > 1) {
1030 tenuring_threshold--;
1031 }
1032 } else if (incr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
1033 if (tenuring_threshold < MaxTenuringThreshold) {
1034 tenuring_threshold++;
1035 }
1036 }
1038 // We keep a running average of the amount promoted which is used
1039 // to decide when we should collect the old generation (when
1040 // the amount of old gen free space is less than what we expect to
1041 // promote).
1043 if (PrintAdaptiveSizePolicy) {
1044 // A little more detail if Verbose is on
1045 if (Verbose) {
1046 gclog_or_tty->print( " avg_survived: %f"
1047 " avg_deviation: %f",
1048 _avg_survived->average(),
1049 _avg_survived->deviation());
1050 }
1052 gclog_or_tty->print( " avg_survived_padded_avg: %f",
1053 _avg_survived->padded_average());
1055 if (Verbose) {
1056 gclog_or_tty->print( " avg_promoted_avg: %f"
1057 " avg_promoted_dev: %f",
1058 avg_promoted()->average(),
1059 avg_promoted()->deviation());
1060 }
1062 gclog_or_tty->print( " avg_promoted_padded_avg: %f"
1063 " avg_pretenured_padded_avg: %f"
1064 " tenuring_thresh: %d"
1065 " target_size: " SIZE_FORMAT,
1066 avg_promoted()->padded_average(),
1067 _avg_pretenured->padded_average(),
1068 tenuring_threshold, target_size);
1069 tty->cr();
1070 }
1072 set_survivor_size(target_size);
1074 return tenuring_threshold;
1075 }
1077 void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
1078 size_t survived,
1079 size_t promoted) {
1080 // Update averages
1081 if (!is_survivor_overflow) {
1082 // Keep running averages on how much survived
1083 _avg_survived->sample(survived);
1084 } else {
1085 size_t survived_guess = survived + promoted;
1086 _avg_survived->sample(survived_guess);
1087 }
1088 avg_promoted()->sample(promoted + _avg_pretenured->padded_average());
1090 if (PrintAdaptiveSizePolicy) {
1091 gclog_or_tty->print(
1092 "AdaptiveSizePolicy::compute_survivor_space_size_and_thresh:"
1093 " survived: " SIZE_FORMAT
1094 " promoted: " SIZE_FORMAT
1095 " overflow: %s",
1096 survived, promoted, is_survivor_overflow ? "true" : "false");
1097 }
1098 }
1100 bool PSAdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st)
1101 const {
1103 if (!UseAdaptiveSizePolicy) return false;
1105 return AdaptiveSizePolicy::print_adaptive_size_policy_on(
1106 st,
1107 PSScavenge::tenuring_threshold());
1108 }