Thu, 05 Jun 2008 15:57:56 -0700
6711316: Open source the Garbage-First garbage collector
Summary: First mercurial integration of the code for the Garbage-First garbage collector.
Reviewed-by: apetrusenko, iveresov, jmasa, sgoldman, tonyp, ysr
duke@435 | 1 | /* |
duke@435 | 2 | * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
duke@435 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
duke@435 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
duke@435 | 21 | * have any questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | #include "incls/_precompiled.incl" |
duke@435 | 25 | #include "incls/_adaptiveSizePolicy.cpp.incl" |
duke@435 | 26 | |
duke@435 | 27 | elapsedTimer AdaptiveSizePolicy::_minor_timer; |
duke@435 | 28 | elapsedTimer AdaptiveSizePolicy::_major_timer; |
duke@435 | 29 | |
duke@435 | 30 | // The throughput goal is implemented as |
duke@435 | 31 | // _throughput_goal = 1 - ( 1 / (1 + gc_cost_ratio)) |
duke@435 | 32 | // gc_cost_ratio is the ratio |
duke@435 | 33 | // application cost / gc cost |
duke@435 | 34 | // For example a gc_cost_ratio of 4 translates into a |
duke@435 | 35 | // throughput goal of .80 |
duke@435 | 36 | |
duke@435 | 37 | AdaptiveSizePolicy::AdaptiveSizePolicy(size_t init_eden_size, |
duke@435 | 38 | size_t init_promo_size, |
duke@435 | 39 | size_t init_survivor_size, |
duke@435 | 40 | double gc_pause_goal_sec, |
duke@435 | 41 | uint gc_cost_ratio) : |
duke@435 | 42 | _eden_size(init_eden_size), |
duke@435 | 43 | _promo_size(init_promo_size), |
duke@435 | 44 | _survivor_size(init_survivor_size), |
duke@435 | 45 | _gc_pause_goal_sec(gc_pause_goal_sec), |
duke@435 | 46 | _throughput_goal(1.0 - double(1.0 / (1.0 + (double) gc_cost_ratio))), |
duke@435 | 47 | _gc_time_limit_exceeded(false), |
duke@435 | 48 | _print_gc_time_limit_would_be_exceeded(false), |
duke@435 | 49 | _gc_time_limit_count(0), |
duke@435 | 50 | _latest_minor_mutator_interval_seconds(0), |
duke@435 | 51 | _threshold_tolerance_percent(1.0 + ThresholdTolerance/100.0), |
duke@435 | 52 | _young_gen_change_for_minor_throughput(0), |
duke@435 | 53 | _old_gen_change_for_major_throughput(0) { |
duke@435 | 54 | _avg_minor_pause = |
duke@435 | 55 | new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding); |
duke@435 | 56 | _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight); |
duke@435 | 57 | _avg_minor_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); |
duke@435 | 58 | _avg_major_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight); |
duke@435 | 59 | |
duke@435 | 60 | _avg_young_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight); |
duke@435 | 61 | _avg_old_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight); |
duke@435 | 62 | _avg_eden_live = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight); |
duke@435 | 63 | |
duke@435 | 64 | _avg_survived = new AdaptivePaddedAverage(AdaptiveSizePolicyWeight, |
duke@435 | 65 | SurvivorPadding); |
duke@435 | 66 | _avg_pretenured = new AdaptivePaddedNoZeroDevAverage( |
duke@435 | 67 | AdaptiveSizePolicyWeight, |
duke@435 | 68 | SurvivorPadding); |
duke@435 | 69 | |
duke@435 | 70 | _minor_pause_old_estimator = |
duke@435 | 71 | new LinearLeastSquareFit(AdaptiveSizePolicyWeight); |
duke@435 | 72 | _minor_pause_young_estimator = |
duke@435 | 73 | new LinearLeastSquareFit(AdaptiveSizePolicyWeight); |
duke@435 | 74 | _minor_collection_estimator = |
duke@435 | 75 | new LinearLeastSquareFit(AdaptiveSizePolicyWeight); |
duke@435 | 76 | _major_collection_estimator = |
duke@435 | 77 | new LinearLeastSquareFit(AdaptiveSizePolicyWeight); |
duke@435 | 78 | |
duke@435 | 79 | // Start the timers |
duke@435 | 80 | _minor_timer.start(); |
duke@435 | 81 | |
duke@435 | 82 | _young_gen_policy_is_ready = false; |
duke@435 | 83 | } |
duke@435 | 84 | |
duke@435 | 85 | bool AdaptiveSizePolicy::tenuring_threshold_change() const { |
duke@435 | 86 | return decrement_tenuring_threshold_for_gc_cost() || |
duke@435 | 87 | increment_tenuring_threshold_for_gc_cost() || |
duke@435 | 88 | decrement_tenuring_threshold_for_survivor_limit(); |
duke@435 | 89 | } |
duke@435 | 90 | |
duke@435 | 91 | void AdaptiveSizePolicy::minor_collection_begin() { |
duke@435 | 92 | // Update the interval time |
duke@435 | 93 | _minor_timer.stop(); |
duke@435 | 94 | // Save most recent collection time |
duke@435 | 95 | _latest_minor_mutator_interval_seconds = _minor_timer.seconds(); |
duke@435 | 96 | _minor_timer.reset(); |
duke@435 | 97 | _minor_timer.start(); |
duke@435 | 98 | } |
duke@435 | 99 | |
duke@435 | 100 | void AdaptiveSizePolicy::update_minor_pause_young_estimator( |
duke@435 | 101 | double minor_pause_in_ms) { |
duke@435 | 102 | double eden_size_in_mbytes = ((double)_eden_size)/((double)M); |
duke@435 | 103 | _minor_pause_young_estimator->update(eden_size_in_mbytes, |
duke@435 | 104 | minor_pause_in_ms); |
duke@435 | 105 | } |
duke@435 | 106 | |
duke@435 | 107 | void AdaptiveSizePolicy::minor_collection_end(GCCause::Cause gc_cause) { |
duke@435 | 108 | // Update the pause time. |
duke@435 | 109 | _minor_timer.stop(); |
duke@435 | 110 | |
duke@435 | 111 | if (gc_cause != GCCause::_java_lang_system_gc || |
duke@435 | 112 | UseAdaptiveSizePolicyWithSystemGC) { |
duke@435 | 113 | double minor_pause_in_seconds = _minor_timer.seconds(); |
duke@435 | 114 | double minor_pause_in_ms = minor_pause_in_seconds * MILLIUNITS; |
duke@435 | 115 | |
duke@435 | 116 | // Sample for performance counter |
duke@435 | 117 | _avg_minor_pause->sample(minor_pause_in_seconds); |
duke@435 | 118 | |
duke@435 | 119 | // Cost of collection (unit-less) |
duke@435 | 120 | double collection_cost = 0.0; |
duke@435 | 121 | if ((_latest_minor_mutator_interval_seconds > 0.0) && |
duke@435 | 122 | (minor_pause_in_seconds > 0.0)) { |
duke@435 | 123 | double interval_in_seconds = |
duke@435 | 124 | _latest_minor_mutator_interval_seconds + minor_pause_in_seconds; |
duke@435 | 125 | collection_cost = |
duke@435 | 126 | minor_pause_in_seconds / interval_in_seconds; |
duke@435 | 127 | _avg_minor_gc_cost->sample(collection_cost); |
duke@435 | 128 | // Sample for performance counter |
duke@435 | 129 | _avg_minor_interval->sample(interval_in_seconds); |
duke@435 | 130 | } |
duke@435 | 131 | |
duke@435 | 132 | // The policy does not have enough data until at least some |
duke@435 | 133 | // minor collections have been done. |
duke@435 | 134 | _young_gen_policy_is_ready = |
duke@435 | 135 | (_avg_minor_gc_cost->count() >= AdaptiveSizePolicyReadyThreshold); |
duke@435 | 136 | |
duke@435 | 137 | // Calculate variables used to estimate pause time vs. gen sizes |
duke@435 | 138 | double eden_size_in_mbytes = ((double)_eden_size)/((double)M); |
duke@435 | 139 | update_minor_pause_young_estimator(minor_pause_in_ms); |
duke@435 | 140 | update_minor_pause_old_estimator(minor_pause_in_ms); |
duke@435 | 141 | |
duke@435 | 142 | if (PrintAdaptiveSizePolicy && Verbose) { |
duke@435 | 143 | gclog_or_tty->print("AdaptiveSizePolicy::minor_collection_end: " |
duke@435 | 144 | "minor gc cost: %f average: %f", collection_cost, |
duke@435 | 145 | _avg_minor_gc_cost->average()); |
duke@435 | 146 | gclog_or_tty->print_cr(" minor pause: %f minor period %f", |
duke@435 | 147 | minor_pause_in_ms, |
duke@435 | 148 | _latest_minor_mutator_interval_seconds * MILLIUNITS); |
duke@435 | 149 | } |
duke@435 | 150 | |
duke@435 | 151 | // Calculate variable used to estimate collection cost vs. gen sizes |
duke@435 | 152 | assert(collection_cost >= 0.0, "Expected to be non-negative"); |
duke@435 | 153 | _minor_collection_estimator->update(eden_size_in_mbytes, collection_cost); |
duke@435 | 154 | } |
duke@435 | 155 | |
duke@435 | 156 | // Interval times use this timer to measure the mutator time. |
duke@435 | 157 | // Reset the timer after the GC pause. |
duke@435 | 158 | _minor_timer.reset(); |
duke@435 | 159 | _minor_timer.start(); |
duke@435 | 160 | } |
duke@435 | 161 | |
duke@435 | 162 | size_t AdaptiveSizePolicy::eden_increment(size_t cur_eden, |
duke@435 | 163 | uint percent_change) { |
duke@435 | 164 | size_t eden_heap_delta; |
duke@435 | 165 | eden_heap_delta = cur_eden / 100 * percent_change; |
duke@435 | 166 | return eden_heap_delta; |
duke@435 | 167 | } |
duke@435 | 168 | |
duke@435 | 169 | size_t AdaptiveSizePolicy::eden_increment(size_t cur_eden) { |
duke@435 | 170 | return eden_increment(cur_eden, YoungGenerationSizeIncrement); |
duke@435 | 171 | } |
duke@435 | 172 | |
duke@435 | 173 | size_t AdaptiveSizePolicy::eden_decrement(size_t cur_eden) { |
duke@435 | 174 | size_t eden_heap_delta = eden_increment(cur_eden) / |
duke@435 | 175 | AdaptiveSizeDecrementScaleFactor; |
duke@435 | 176 | return eden_heap_delta; |
duke@435 | 177 | } |
duke@435 | 178 | |
duke@435 | 179 | size_t AdaptiveSizePolicy::promo_increment(size_t cur_promo, |
duke@435 | 180 | uint percent_change) { |
duke@435 | 181 | size_t promo_heap_delta; |
duke@435 | 182 | promo_heap_delta = cur_promo / 100 * percent_change; |
duke@435 | 183 | return promo_heap_delta; |
duke@435 | 184 | } |
duke@435 | 185 | |
duke@435 | 186 | size_t AdaptiveSizePolicy::promo_increment(size_t cur_promo) { |
duke@435 | 187 | return promo_increment(cur_promo, TenuredGenerationSizeIncrement); |
duke@435 | 188 | } |
duke@435 | 189 | |
duke@435 | 190 | size_t AdaptiveSizePolicy::promo_decrement(size_t cur_promo) { |
duke@435 | 191 | size_t promo_heap_delta = promo_increment(cur_promo); |
duke@435 | 192 | promo_heap_delta = promo_heap_delta / AdaptiveSizeDecrementScaleFactor; |
duke@435 | 193 | return promo_heap_delta; |
duke@435 | 194 | } |
duke@435 | 195 | |
duke@435 | 196 | double AdaptiveSizePolicy::time_since_major_gc() const { |
duke@435 | 197 | _major_timer.stop(); |
duke@435 | 198 | double result = _major_timer.seconds(); |
duke@435 | 199 | _major_timer.start(); |
duke@435 | 200 | return result; |
duke@435 | 201 | } |
duke@435 | 202 | |
duke@435 | 203 | // Linear decay of major gc cost |
duke@435 | 204 | double AdaptiveSizePolicy::decaying_major_gc_cost() const { |
duke@435 | 205 | double major_interval = major_gc_interval_average_for_decay(); |
duke@435 | 206 | double major_gc_cost_average = major_gc_cost(); |
duke@435 | 207 | double decayed_major_gc_cost = major_gc_cost_average; |
duke@435 | 208 | if(time_since_major_gc() > 0.0) { |
duke@435 | 209 | decayed_major_gc_cost = major_gc_cost() * |
duke@435 | 210 | (((double) AdaptiveSizeMajorGCDecayTimeScale) * major_interval) |
duke@435 | 211 | / time_since_major_gc(); |
duke@435 | 212 | } |
duke@435 | 213 | |
duke@435 | 214 | // The decayed cost should always be smaller than the |
duke@435 | 215 | // average cost but the vagaries of finite arithmetic could |
duke@435 | 216 | // produce a larger value in decayed_major_gc_cost so protect |
duke@435 | 217 | // against that. |
duke@435 | 218 | return MIN2(major_gc_cost_average, decayed_major_gc_cost); |
duke@435 | 219 | } |
duke@435 | 220 | |
duke@435 | 221 | // Use a value of the major gc cost that has been decayed |
duke@435 | 222 | // by the factor |
duke@435 | 223 | // |
duke@435 | 224 | // average-interval-between-major-gc * AdaptiveSizeMajorGCDecayTimeScale / |
duke@435 | 225 | // time-since-last-major-gc |
duke@435 | 226 | // |
duke@435 | 227 | // if the average-interval-between-major-gc * AdaptiveSizeMajorGCDecayTimeScale |
duke@435 | 228 | // is less than time-since-last-major-gc. |
duke@435 | 229 | // |
duke@435 | 230 | // In cases where there are initial major gc's that |
duke@435 | 231 | // are of a relatively high cost but no later major |
duke@435 | 232 | // gc's, the total gc cost can remain high because |
duke@435 | 233 | // the major gc cost remains unchanged (since there are no major |
duke@435 | 234 | // gc's). In such a situation the value of the unchanging |
duke@435 | 235 | // major gc cost can keep the mutator throughput below |
duke@435 | 236 | // the goal when in fact the major gc cost is becoming diminishingly |
duke@435 | 237 | // small. Use the decaying gc cost only to decide whether to |
duke@435 | 238 | // adjust for throughput. Using it also to determine the adjustment |
duke@435 | 239 | // to be made for throughput also seems reasonable but there is |
duke@435 | 240 | // no test case to use to decide if it is the right thing to do |
duke@435 | 241 | // don't do it yet. |
duke@435 | 242 | |
duke@435 | 243 | double AdaptiveSizePolicy::decaying_gc_cost() const { |
duke@435 | 244 | double decayed_major_gc_cost = major_gc_cost(); |
duke@435 | 245 | double avg_major_interval = major_gc_interval_average_for_decay(); |
duke@435 | 246 | if (UseAdaptiveSizeDecayMajorGCCost && |
duke@435 | 247 | (AdaptiveSizeMajorGCDecayTimeScale > 0) && |
duke@435 | 248 | (avg_major_interval > 0.00)) { |
duke@435 | 249 | double time_since_last_major_gc = time_since_major_gc(); |
duke@435 | 250 | |
duke@435 | 251 | // Decay the major gc cost? |
duke@435 | 252 | if (time_since_last_major_gc > |
duke@435 | 253 | ((double) AdaptiveSizeMajorGCDecayTimeScale) * avg_major_interval) { |
duke@435 | 254 | |
duke@435 | 255 | // Decay using the time-since-last-major-gc |
duke@435 | 256 | decayed_major_gc_cost = decaying_major_gc_cost(); |
duke@435 | 257 | if (PrintGCDetails && Verbose) { |
duke@435 | 258 | gclog_or_tty->print_cr("\ndecaying_gc_cost: major interval average:" |
duke@435 | 259 | " %f time since last major gc: %f", |
duke@435 | 260 | avg_major_interval, time_since_last_major_gc); |
duke@435 | 261 | gclog_or_tty->print_cr(" major gc cost: %f decayed major gc cost: %f", |
duke@435 | 262 | major_gc_cost(), decayed_major_gc_cost); |
duke@435 | 263 | } |
duke@435 | 264 | } |
duke@435 | 265 | } |
duke@435 | 266 | double result = MIN2(1.0, decayed_major_gc_cost + minor_gc_cost()); |
duke@435 | 267 | return result; |
duke@435 | 268 | } |
duke@435 | 269 | |
duke@435 | 270 | |
duke@435 | 271 | void AdaptiveSizePolicy::clear_generation_free_space_flags() { |
duke@435 | 272 | set_change_young_gen_for_min_pauses(0); |
duke@435 | 273 | set_change_old_gen_for_maj_pauses(0); |
duke@435 | 274 | |
duke@435 | 275 | set_change_old_gen_for_throughput(0); |
duke@435 | 276 | set_change_young_gen_for_throughput(0); |
duke@435 | 277 | set_decrease_for_footprint(0); |
duke@435 | 278 | set_decide_at_full_gc(0); |
duke@435 | 279 | } |
duke@435 | 280 | |
duke@435 | 281 | // Printing |
duke@435 | 282 | |
duke@435 | 283 | bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const { |
duke@435 | 284 | |
duke@435 | 285 | // Should only be used with adaptive size policy turned on. |
duke@435 | 286 | // Otherwise, there may be variables that are undefined. |
duke@435 | 287 | if (!UseAdaptiveSizePolicy) return false; |
duke@435 | 288 | |
duke@435 | 289 | // Print goal for which action is needed. |
duke@435 | 290 | char* action = NULL; |
duke@435 | 291 | bool change_for_pause = false; |
duke@435 | 292 | if ((change_old_gen_for_maj_pauses() == |
duke@435 | 293 | decrease_old_gen_for_maj_pauses_true) || |
duke@435 | 294 | (change_young_gen_for_min_pauses() == |
duke@435 | 295 | decrease_young_gen_for_min_pauses_true)) { |
duke@435 | 296 | action = (char*) " *** pause time goal ***"; |
duke@435 | 297 | change_for_pause = true; |
duke@435 | 298 | } else if ((change_old_gen_for_throughput() == |
duke@435 | 299 | increase_old_gen_for_throughput_true) || |
duke@435 | 300 | (change_young_gen_for_throughput() == |
duke@435 | 301 | increase_young_gen_for_througput_true)) { |
duke@435 | 302 | action = (char*) " *** throughput goal ***"; |
duke@435 | 303 | } else if (decrease_for_footprint()) { |
duke@435 | 304 | action = (char*) " *** reduced footprint ***"; |
duke@435 | 305 | } else { |
duke@435 | 306 | // No actions were taken. This can legitimately be the |
duke@435 | 307 | // situation if not enough data has been gathered to make |
duke@435 | 308 | // decisions. |
duke@435 | 309 | return false; |
duke@435 | 310 | } |
duke@435 | 311 | |
duke@435 | 312 | // Pauses |
duke@435 | 313 | // Currently the size of the old gen is only adjusted to |
duke@435 | 314 | // change the major pause times. |
duke@435 | 315 | char* young_gen_action = NULL; |
duke@435 | 316 | char* tenured_gen_action = NULL; |
duke@435 | 317 | |
duke@435 | 318 | char* shrink_msg = (char*) "(attempted to shrink)"; |
duke@435 | 319 | char* grow_msg = (char*) "(attempted to grow)"; |
duke@435 | 320 | char* no_change_msg = (char*) "(no change)"; |
duke@435 | 321 | if (change_young_gen_for_min_pauses() == |
duke@435 | 322 | decrease_young_gen_for_min_pauses_true) { |
duke@435 | 323 | young_gen_action = shrink_msg; |
duke@435 | 324 | } else if (change_for_pause) { |
duke@435 | 325 | young_gen_action = no_change_msg; |
duke@435 | 326 | } |
duke@435 | 327 | |
duke@435 | 328 | if (change_old_gen_for_maj_pauses() == decrease_old_gen_for_maj_pauses_true) { |
duke@435 | 329 | tenured_gen_action = shrink_msg; |
duke@435 | 330 | } else if (change_for_pause) { |
duke@435 | 331 | tenured_gen_action = no_change_msg; |
duke@435 | 332 | } |
duke@435 | 333 | |
duke@435 | 334 | // Throughput |
duke@435 | 335 | if (change_old_gen_for_throughput() == increase_old_gen_for_throughput_true) { |
duke@435 | 336 | assert(change_young_gen_for_throughput() == |
duke@435 | 337 | increase_young_gen_for_througput_true, |
duke@435 | 338 | "Both generations should be growing"); |
duke@435 | 339 | young_gen_action = grow_msg; |
duke@435 | 340 | tenured_gen_action = grow_msg; |
duke@435 | 341 | } else if (change_young_gen_for_throughput() == |
duke@435 | 342 | increase_young_gen_for_througput_true) { |
duke@435 | 343 | // Only the young generation may grow at start up (before |
duke@435 | 344 | // enough full collections have been done to grow the old generation). |
duke@435 | 345 | young_gen_action = grow_msg; |
duke@435 | 346 | tenured_gen_action = no_change_msg; |
duke@435 | 347 | } |
duke@435 | 348 | |
duke@435 | 349 | // Minimum footprint |
duke@435 | 350 | if (decrease_for_footprint() != 0) { |
duke@435 | 351 | young_gen_action = shrink_msg; |
duke@435 | 352 | tenured_gen_action = shrink_msg; |
duke@435 | 353 | } |
duke@435 | 354 | |
duke@435 | 355 | st->print_cr(" UseAdaptiveSizePolicy actions to meet %s", action); |
duke@435 | 356 | st->print_cr(" GC overhead (%%)"); |
duke@435 | 357 | st->print_cr(" Young generation: %7.2f\t %s", |
duke@435 | 358 | 100.0 * avg_minor_gc_cost()->average(), |
duke@435 | 359 | young_gen_action); |
duke@435 | 360 | st->print_cr(" Tenured generation: %7.2f\t %s", |
duke@435 | 361 | 100.0 * avg_major_gc_cost()->average(), |
duke@435 | 362 | tenured_gen_action); |
duke@435 | 363 | return true; |
duke@435 | 364 | } |
duke@435 | 365 | |
duke@435 | 366 | bool AdaptiveSizePolicy::print_adaptive_size_policy_on( |
duke@435 | 367 | outputStream* st, |
duke@435 | 368 | int tenuring_threshold_arg) const { |
duke@435 | 369 | if (!AdaptiveSizePolicy::print_adaptive_size_policy_on(st)) { |
duke@435 | 370 | return false; |
duke@435 | 371 | } |
duke@435 | 372 | |
duke@435 | 373 | // Tenuring threshold |
duke@435 | 374 | bool tenuring_threshold_changed = true; |
duke@435 | 375 | if (decrement_tenuring_threshold_for_survivor_limit()) { |
duke@435 | 376 | st->print(" Tenuring threshold: (attempted to decrease to avoid" |
duke@435 | 377 | " survivor space overflow) = "); |
duke@435 | 378 | } else if (decrement_tenuring_threshold_for_gc_cost()) { |
duke@435 | 379 | st->print(" Tenuring threshold: (attempted to decrease to balance" |
duke@435 | 380 | " GC costs) = "); |
duke@435 | 381 | } else if (increment_tenuring_threshold_for_gc_cost()) { |
duke@435 | 382 | st->print(" Tenuring threshold: (attempted to increase to balance" |
duke@435 | 383 | " GC costs) = "); |
duke@435 | 384 | } else { |
duke@435 | 385 | tenuring_threshold_changed = false; |
duke@435 | 386 | assert(!tenuring_threshold_change(), "(no change was attempted)"); |
duke@435 | 387 | } |
duke@435 | 388 | if (tenuring_threshold_changed) { |
duke@435 | 389 | st->print_cr("%d", tenuring_threshold_arg); |
duke@435 | 390 | } |
duke@435 | 391 | return true; |
duke@435 | 392 | } |