src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

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

mercurial