Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp @ 10288:eba99d16dc6f
8007763: Refactoring: split up compute_generation_free_space() into two functions for class PSAdaptiveSizePolicy
Summary: split up compute_generation_free_space() into two functions: compute_eden_space_size() + compute_old_gen_free_space(), each of which (if needed) can be reused without executing an overhead of the other.
Reviewed-by: jmasa, tschatzl
Contributed-by: tamao <tao.mao@oracle.com>
author | tamao |
---|---|
date | Wed, 15 May 2013 10:41:22 -0700 |
parents | 22b8d3d181d9 |
children | 14d3f71f831d |
comparison
equal
deleted
inserted
replaced
10287:12f651e29f6b | 10288:eba99d16dc6f |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
199 size_t eden_live, | 199 size_t eden_live, |
200 size_t old_live, | 200 size_t old_live, |
201 size_t cur_eden, | 201 size_t cur_eden, |
202 size_t max_old_gen_size, | 202 size_t max_old_gen_size, |
203 size_t max_eden_size, | 203 size_t max_eden_size, |
204 bool is_full_gc, | 204 bool is_full_gc) { |
205 GCCause::Cause gc_cause, | 205 compute_eden_space_size(young_live, |
206 CollectorPolicy* collector_policy) { | 206 eden_live, |
207 cur_eden, | |
208 max_eden_size, | |
209 is_full_gc); | |
210 | |
211 compute_old_gen_free_space(old_live, | |
212 cur_eden, | |
213 max_old_gen_size, | |
214 is_full_gc); | |
215 } | |
216 | |
217 void PSAdaptiveSizePolicy::compute_eden_space_size( | |
218 size_t young_live, | |
219 size_t eden_live, | |
220 size_t cur_eden, | |
221 size_t max_eden_size, | |
222 bool is_full_gc) { | |
207 | 223 |
208 // Update statistics | 224 // Update statistics |
209 // Time statistics are updated as we go, update footprint stats here | 225 // Time statistics are updated as we go, update footprint stats here |
210 _avg_base_footprint->sample(BaseFootPrintEstimate); | 226 _avg_base_footprint->sample(BaseFootPrintEstimate); |
211 avg_young_live()->sample(young_live); | 227 avg_young_live()->sample(young_live); |
212 avg_eden_live()->sample(eden_live); | 228 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 } | |
217 | 229 |
218 // This code used to return if the policy was not ready , i.e., | 230 // This code used to return if the policy was not ready , i.e., |
219 // policy_is_ready() returning false. The intent was that | 231 // policy_is_ready() returning false. The intent was that |
220 // decisions below needed major collection times and so could | 232 // decisions below needed major collection times and so could |
221 // not be made before two major collections. A consequence was | 233 // not be made before two major collections. A consequence was |
240 // caused desired_eden_size to grow way too large and caused | 252 // caused desired_eden_size to grow way too large and caused |
241 // an overflow down stream. It may have improved performance in | 253 // an overflow down stream. It may have improved performance in |
242 // some case but is dangerous. | 254 // some case but is dangerous. |
243 size_t desired_eden_size = cur_eden; | 255 size_t desired_eden_size = cur_eden; |
244 | 256 |
245 #ifdef ASSERT | |
246 size_t original_promo_size = desired_promo_size; | |
247 size_t original_eden_size = desired_eden_size; | |
248 #endif | |
249 | |
250 // Cache some values. There's a bit of work getting these, so | 257 // Cache some values. There's a bit of work getting these, so |
251 // we might save a little time. | 258 // we might save a little time. |
252 const double major_cost = major_gc_cost(); | 259 const double major_cost = major_gc_cost(); |
253 const double minor_cost = minor_gc_cost(); | 260 const double minor_cost = minor_gc_cost(); |
254 | |
255 // Used for diagnostics | |
256 clear_generation_free_space_flags(); | |
257 | |
258 // Limits on our growth | |
259 size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average()); | |
260 | 261 |
261 // This method sets the desired eden size. That plus the | 262 // This method sets the desired eden size. That plus the |
262 // desired survivor space sizes sets the desired young generation | 263 // desired survivor space sizes sets the desired young generation |
263 // size. This methods does not know what the desired survivor | 264 // size. This methods does not know what the desired survivor |
264 // size is but expects that other policy will attempt to make | 265 // size is but expects that other policy will attempt to make |
265 // the survivor sizes compatible with the live data in the | 266 // the survivor sizes compatible with the live data in the |
266 // young generation. This limit is an estimate of the space left | 267 // young generation. This limit is an estimate of the space left |
267 // in the young generation after the survivor spaces have been | 268 // in the young generation after the survivor spaces have been |
268 // subtracted out. | 269 // subtracted out. |
269 size_t eden_limit = max_eden_size; | 270 size_t eden_limit = max_eden_size; |
270 | |
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); | |
274 | 271 |
275 const double gc_cost_limit = GCTimeLimit/100.0; | 272 const double gc_cost_limit = GCTimeLimit/100.0; |
276 | 273 |
277 // Which way should we go? | 274 // Which way should we go? |
278 // if pause requirement is not met | 275 // if pause requirement is not met |
284 // adjust one generation at a time. | 281 // adjust one generation at a time. |
285 // else | 282 // else |
286 // adjust down the total heap size. Adjust down the larger of the | 283 // adjust down the total heap size. Adjust down the larger of the |
287 // generations. | 284 // generations. |
288 | 285 |
289 // Add some checks for a threshhold for a change. For example, | 286 // Add some checks for a threshold for a change. For example, |
290 // a change less than the necessary alignment is probably not worth | 287 // a change less than the necessary alignment is probably not worth |
291 // attempting. | 288 // attempting. |
292 | 289 |
293 | 290 |
294 if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) || | 291 if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) || |
296 // | 293 // |
297 // Check pauses | 294 // Check pauses |
298 // | 295 // |
299 // Make changes only to affect one of the pauses (the larger) | 296 // Make changes only to affect one of the pauses (the larger) |
300 // at a time. | 297 // at a time. |
301 adjust_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size); | 298 adjust_eden_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size); |
302 | 299 |
303 } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) { | 300 } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) { |
304 // Adjust only for the minor pause time goal | 301 // Adjust only for the minor pause time goal |
305 adjust_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size); | 302 adjust_eden_for_minor_pause_time(is_full_gc, &desired_eden_size); |
306 | 303 |
307 } else if(adjusted_mutator_cost() < _throughput_goal) { | 304 } else if(adjusted_mutator_cost() < _throughput_goal) { |
308 // This branch used to require that (mutator_cost() > 0.0 in 1.4.2. | 305 // This branch used to require that (mutator_cost() > 0.0 in 1.4.2. |
309 // This sometimes resulted in skipping to the minimize footprint | 306 // This sometimes resulted in skipping to the minimize footprint |
310 // code. Change this to try and reduce GC time if mutator time is | 307 // code. Change this to try and reduce GC time if mutator time is |
314 // Throughput | 311 // Throughput |
315 // | 312 // |
316 assert(major_cost >= 0.0, "major cost is < 0.0"); | 313 assert(major_cost >= 0.0, "major cost is < 0.0"); |
317 assert(minor_cost >= 0.0, "minor cost is < 0.0"); | 314 assert(minor_cost >= 0.0, "minor cost is < 0.0"); |
318 // Try to reduce the GC times. | 315 // Try to reduce the GC times. |
319 adjust_for_throughput(is_full_gc, &desired_promo_size, &desired_eden_size); | 316 adjust_eden_for_throughput(is_full_gc, &desired_eden_size); |
320 | 317 |
321 } else { | 318 } else { |
322 | 319 |
323 // Be conservative about reducing the footprint. | 320 // Be conservative about reducing the footprint. |
324 // Do a minimum number of major collections first. | 321 // Do a minimum number of major collections first. |
326 if (UseAdaptiveSizePolicyFootprintGoal && | 323 if (UseAdaptiveSizePolicyFootprintGoal && |
327 young_gen_policy_is_ready() && | 324 young_gen_policy_is_ready() && |
328 avg_major_gc_cost()->average() >= 0.0 && | 325 avg_major_gc_cost()->average() >= 0.0 && |
329 avg_minor_gc_cost()->average() >= 0.0) { | 326 avg_minor_gc_cost()->average() >= 0.0) { |
330 size_t desired_sum = desired_eden_size + desired_promo_size; | 327 size_t desired_sum = desired_eden_size + desired_promo_size; |
331 desired_eden_size = adjust_eden_for_footprint(desired_eden_size, | 328 desired_eden_size = adjust_eden_for_footprint(desired_eden_size, desired_sum); |
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 } | 329 } |
339 } | 330 } |
340 | 331 |
341 // Note we make the same tests as in the code block below; the code | 332 // 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. | 333 // seems a little easier to read with the printing in another block. |
343 if (PrintAdaptiveSizePolicy) { | 334 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) { | 335 if (desired_eden_size > eden_limit) { |
358 gclog_or_tty->print_cr( | 336 gclog_or_tty->print_cr( |
359 "AdaptiveSizePolicy::compute_generation_free_space limits:" | 337 "PSAdaptiveSizePolicy::compute_eden_space_size limits:" |
360 " desired_eden_size: " SIZE_FORMAT | 338 " desired_eden_size: " SIZE_FORMAT |
361 " old_eden_size: " SIZE_FORMAT | 339 " old_eden_size: " SIZE_FORMAT |
362 " eden_limit: " SIZE_FORMAT | 340 " eden_limit: " SIZE_FORMAT |
363 " cur_eden: " SIZE_FORMAT | 341 " cur_eden: " SIZE_FORMAT |
364 " max_eden_size: " SIZE_FORMAT | 342 " max_eden_size: " SIZE_FORMAT |
366 desired_eden_size, _eden_size, eden_limit, cur_eden, | 344 desired_eden_size, _eden_size, eden_limit, cur_eden, |
367 max_eden_size, (size_t)avg_young_live()->average()); | 345 max_eden_size, (size_t)avg_young_live()->average()); |
368 } | 346 } |
369 if (gc_cost() > gc_cost_limit) { | 347 if (gc_cost() > gc_cost_limit) { |
370 gclog_or_tty->print_cr( | 348 gclog_or_tty->print_cr( |
371 "AdaptiveSizePolicy::compute_generation_free_space: gc time limit" | 349 "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit" |
372 " gc_cost: %f " | 350 " gc_cost: %f " |
373 " GCTimeLimit: %d", | 351 " GCTimeLimit: %d", |
374 gc_cost(), GCTimeLimit); | 352 gc_cost(), GCTimeLimit); |
375 } | 353 } |
376 } | 354 } |
377 | 355 |
378 // Align everything and make a final limit check | 356 // Align everything and make a final limit check |
379 const size_t alignment = _intra_generation_alignment; | 357 const size_t alignment = _intra_generation_alignment; |
380 desired_eden_size = align_size_up(desired_eden_size, alignment); | 358 desired_eden_size = align_size_up(desired_eden_size, alignment); |
381 desired_eden_size = MAX2(desired_eden_size, alignment); | 359 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); | |
384 | 360 |
385 eden_limit = align_size_down(eden_limit, alignment); | 361 eden_limit = align_size_down(eden_limit, alignment); |
386 promo_limit = align_size_down(promo_limit, alignment); | |
387 | |
388 // Is too much time being spent in GC? | |
389 // Is the heap trying to grow beyond it's limits? | |
390 | |
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 } | |
402 | |
403 | 362 |
404 // And one last limit check, now that we've aligned things. | 363 // And one last limit check, now that we've aligned things. |
405 if (desired_eden_size > eden_limit) { | 364 if (desired_eden_size > eden_limit) { |
406 // If the policy says to get a larger eden but | 365 // If the policy says to get a larger eden but |
407 // is hitting the limit, don't decrease eden. | 366 // is hitting the limit, don't decrease eden. |
408 // This can lead to a general drifting down of the | 367 // This can lead to a general drifting down of the |
409 // eden size. Let the tenuring calculation push more | 368 // eden size. Let the tenuring calculation push more |
410 // into the old gen. | 369 // into the old gen. |
411 desired_eden_size = MAX2(eden_limit, cur_eden); | 370 desired_eden_size = MAX2(eden_limit, cur_eden); |
412 } | 371 } |
413 desired_promo_size = MIN2(desired_promo_size, promo_limit); | |
414 | |
415 | 372 |
416 if (PrintAdaptiveSizePolicy) { | 373 if (PrintAdaptiveSizePolicy) { |
417 // Timing stats | 374 // Timing stats |
418 gclog_or_tty->print( | 375 gclog_or_tty->print( |
419 "PSAdaptiveSizePolicy::compute_generation_free_space: costs" | 376 "PSAdaptiveSizePolicy::compute_eden_space_size: costs" |
420 " minor_time: %f" | 377 " minor_time: %f" |
421 " major_cost: %f" | 378 " major_cost: %f" |
422 " mutator_cost: %f" | 379 " mutator_cost: %f" |
423 " throughput_goal: %f", | 380 " throughput_goal: %f", |
424 minor_gc_cost(), major_gc_cost(), mutator_cost(), | 381 minor_gc_cost(), major_gc_cost(), mutator_cost(), |
451 (size_t)avg_young_live()->average(), | 408 (size_t)avg_young_live()->average(), |
452 (size_t)avg_old_live()->average()); | 409 (size_t)avg_old_live()->average()); |
453 } | 410 } |
454 | 411 |
455 // And finally, our old and new sizes. | 412 // And finally, our old and new sizes. |
413 gclog_or_tty->print(" old_eden_size: " SIZE_FORMAT | |
414 " desired_eden_size: " SIZE_FORMAT, | |
415 _eden_size, desired_eden_size); | |
416 gclog_or_tty->cr(); | |
417 } | |
418 | |
419 set_eden_size(desired_eden_size); | |
420 } | |
421 | |
422 void PSAdaptiveSizePolicy::compute_old_gen_free_space( | |
423 size_t old_live, | |
424 size_t cur_eden, | |
425 size_t max_old_gen_size, | |
426 bool is_full_gc) { | |
427 | |
428 // Update statistics | |
429 // Time statistics are updated as we go, update footprint stats here | |
430 if (is_full_gc) { | |
431 // old_live is only accurate after a full gc | |
432 avg_old_live()->sample(old_live); | |
433 } | |
434 | |
435 // This code used to return if the policy was not ready , i.e., | |
436 // policy_is_ready() returning false. The intent was that | |
437 // decisions below needed major collection times and so could | |
438 // not be made before two major collections. A consequence was | |
439 // adjustments to the young generation were not done until after | |
440 // two major collections even if the minor collections times | |
441 // exceeded the requested goals. Now let the young generation | |
442 // adjust for the minor collection times. Major collection times | |
443 // will be zero for the first collection and will naturally be | |
444 // ignored. Tenured generation adjustments are only made at the | |
445 // full collections so until the second major collection has | |
446 // been reached, no tenured generation adjustments will be made. | |
447 | |
448 // Until we know better, desired promotion size uses the last calculation | |
449 size_t desired_promo_size = _promo_size; | |
450 | |
451 // Start eden at the current value. The desired value that is stored | |
452 // in _eden_size is not bounded by constraints of the heap and can | |
453 // run away. | |
454 // | |
455 // As expected setting desired_eden_size to the current | |
456 // value of desired_eden_size as a starting point | |
457 // caused desired_eden_size to grow way too large and caused | |
458 // an overflow down stream. It may have improved performance in | |
459 // some case but is dangerous. | |
460 size_t desired_eden_size = cur_eden; | |
461 | |
462 // Cache some values. There's a bit of work getting these, so | |
463 // we might save a little time. | |
464 const double major_cost = major_gc_cost(); | |
465 const double minor_cost = minor_gc_cost(); | |
466 | |
467 // Limits on our growth | |
468 size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average()); | |
469 | |
470 // But don't force a promo size below the current promo size. Otherwise, | |
471 // the promo size will shrink for no good reason. | |
472 promo_limit = MAX2(promo_limit, _promo_size); | |
473 | |
474 const double gc_cost_limit = GCTimeLimit/100.0; | |
475 | |
476 // Which way should we go? | |
477 // if pause requirement is not met | |
478 // adjust size of any generation with average paus exceeding | |
479 // the pause limit. Adjust one pause at a time (the larger) | |
480 // and only make adjustments for the major pause at full collections. | |
481 // else if throughput requirement not met | |
482 // adjust the size of the generation with larger gc time. Only | |
483 // adjust one generation at a time. | |
484 // else | |
485 // adjust down the total heap size. Adjust down the larger of the | |
486 // generations. | |
487 | |
488 // Add some checks for a threshhold for a change. For example, | |
489 // a change less than the necessary alignment is probably not worth | |
490 // attempting. | |
491 | |
492 if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) || | |
493 (_avg_major_pause->padded_average() > gc_pause_goal_sec())) { | |
494 // | |
495 // Check pauses | |
496 // | |
497 // Make changes only to affect one of the pauses (the larger) | |
498 // at a time. | |
499 if (is_full_gc) { | |
500 set_decide_at_full_gc(decide_at_full_gc_true); | |
501 adjust_promo_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size); | |
502 } | |
503 } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) { | |
504 // Adjust only for the minor pause time goal | |
505 adjust_promo_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size); | |
506 } else if(adjusted_mutator_cost() < _throughput_goal) { | |
507 // This branch used to require that (mutator_cost() > 0.0 in 1.4.2. | |
508 // This sometimes resulted in skipping to the minimize footprint | |
509 // code. Change this to try and reduce GC time if mutator time is | |
510 // negative for whatever reason. Or for future consideration, | |
511 // bail out of the code if mutator time is negative. | |
512 // | |
513 // Throughput | |
514 // | |
515 assert(major_cost >= 0.0, "major cost is < 0.0"); | |
516 assert(minor_cost >= 0.0, "minor cost is < 0.0"); | |
517 // Try to reduce the GC times. | |
518 if (is_full_gc) { | |
519 set_decide_at_full_gc(decide_at_full_gc_true); | |
520 adjust_promo_for_throughput(is_full_gc, &desired_promo_size); | |
521 } | |
522 } else { | |
523 | |
524 // Be conservative about reducing the footprint. | |
525 // Do a minimum number of major collections first. | |
526 // Have reasonable averages for major and minor collections costs. | |
527 if (UseAdaptiveSizePolicyFootprintGoal && | |
528 young_gen_policy_is_ready() && | |
529 avg_major_gc_cost()->average() >= 0.0 && | |
530 avg_minor_gc_cost()->average() >= 0.0) { | |
531 if (is_full_gc) { | |
532 set_decide_at_full_gc(decide_at_full_gc_true); | |
533 size_t desired_sum = desired_eden_size + desired_promo_size; | |
534 desired_promo_size = adjust_promo_for_footprint(desired_promo_size, desired_sum); | |
535 } | |
536 } | |
537 } | |
538 | |
539 // Note we make the same tests as in the code block below; the code | |
540 // seems a little easier to read with the printing in another block. | |
541 if (PrintAdaptiveSizePolicy) { | |
542 if (desired_promo_size > promo_limit) { | |
543 // "free_in_old_gen" was the original value for used for promo_limit | |
544 size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average()); | |
545 gclog_or_tty->print_cr( | |
546 "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:" | |
547 " desired_promo_size: " SIZE_FORMAT | |
548 " promo_limit: " SIZE_FORMAT | |
549 " free_in_old_gen: " SIZE_FORMAT | |
550 " max_old_gen_size: " SIZE_FORMAT | |
551 " avg_old_live: " SIZE_FORMAT, | |
552 desired_promo_size, promo_limit, free_in_old_gen, | |
553 max_old_gen_size, (size_t) avg_old_live()->average()); | |
554 } | |
555 if (gc_cost() > gc_cost_limit) { | |
556 gclog_or_tty->print_cr( | |
557 "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit" | |
558 " gc_cost: %f " | |
559 " GCTimeLimit: %d", | |
560 gc_cost(), GCTimeLimit); | |
561 } | |
562 } | |
563 | |
564 // Align everything and make a final limit check | |
565 const size_t alignment = _intra_generation_alignment; | |
566 desired_promo_size = align_size_up(desired_promo_size, alignment); | |
567 desired_promo_size = MAX2(desired_promo_size, alignment); | |
568 | |
569 promo_limit = align_size_down(promo_limit, alignment); | |
570 | |
571 // And one last limit check, now that we've aligned things. | |
572 desired_promo_size = MIN2(desired_promo_size, promo_limit); | |
573 | |
574 if (PrintAdaptiveSizePolicy) { | |
575 // Timing stats | |
576 gclog_or_tty->print( | |
577 "PSAdaptiveSizePolicy::compute_old_gen_free_space: costs" | |
578 " minor_time: %f" | |
579 " major_cost: %f" | |
580 " mutator_cost: %f" | |
581 " throughput_goal: %f", | |
582 minor_gc_cost(), major_gc_cost(), mutator_cost(), | |
583 _throughput_goal); | |
584 | |
585 // We give more details if Verbose is set | |
586 if (Verbose) { | |
587 gclog_or_tty->print( " minor_pause: %f" | |
588 " major_pause: %f" | |
589 " minor_interval: %f" | |
590 " major_interval: %f" | |
591 " pause_goal: %f", | |
592 _avg_minor_pause->padded_average(), | |
593 _avg_major_pause->padded_average(), | |
594 _avg_minor_interval->average(), | |
595 _avg_major_interval->average(), | |
596 gc_pause_goal_sec()); | |
597 } | |
598 | |
599 // Footprint stats | |
600 gclog_or_tty->print( " live_space: " SIZE_FORMAT | |
601 " free_space: " SIZE_FORMAT, | |
602 live_space(), free_space()); | |
603 // More detail | |
604 if (Verbose) { | |
605 gclog_or_tty->print( " base_footprint: " SIZE_FORMAT | |
606 " avg_young_live: " SIZE_FORMAT | |
607 " avg_old_live: " SIZE_FORMAT, | |
608 (size_t)_avg_base_footprint->average(), | |
609 (size_t)avg_young_live()->average(), | |
610 (size_t)avg_old_live()->average()); | |
611 } | |
612 | |
613 // And finally, our old and new sizes. | |
456 gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT | 614 gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT |
457 " old_eden_size: " SIZE_FORMAT | 615 " desired_promo_size: " SIZE_FORMAT, |
458 " desired_promo_size: " SIZE_FORMAT | 616 _promo_size, desired_promo_size); |
459 " desired_eden_size: " SIZE_FORMAT, | |
460 _promo_size, _eden_size, | |
461 desired_promo_size, desired_eden_size); | |
462 gclog_or_tty->cr(); | 617 gclog_or_tty->cr(); |
463 } | 618 } |
464 | 619 |
465 decay_supplemental_growth(is_full_gc); | |
466 | |
467 set_promo_size(desired_promo_size); | 620 set_promo_size(desired_promo_size); |
468 set_eden_size(desired_eden_size); | 621 } |
469 }; | |
470 | 622 |
471 void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) { | 623 void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) { |
472 // Decay the supplemental increment? Decay the supplement growth | 624 // Decay the supplemental increment? Decay the supplement growth |
473 // factor even if it is not used. It is only meant to give a boost | 625 // 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 | 626 // to the initial growth and if it is not used, then it was not |
488 _young_gen_size_increment_supplement >> 1; | 640 _young_gen_size_increment_supplement >> 1; |
489 } | 641 } |
490 } | 642 } |
491 } | 643 } |
492 | 644 |
493 void PSAdaptiveSizePolicy::adjust_for_minor_pause_time(bool is_full_gc, | 645 void PSAdaptiveSizePolicy::adjust_promo_for_minor_pause_time(bool is_full_gc, |
494 size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr) { | 646 size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr) { |
647 | |
648 if (PSAdjustTenuredGenForMinorPause) { | |
649 if (is_full_gc) { | |
650 set_decide_at_full_gc(decide_at_full_gc_true); | |
651 } | |
652 // If the desired eden size is as small as it will get, | |
653 // try to adjust the old gen size. | |
654 if (*desired_eden_size_ptr <= _intra_generation_alignment) { | |
655 // Vary the old gen size to reduce the young gen pause. This | |
656 // may not be a good idea. This is just a test. | |
657 if (minor_pause_old_estimator()->decrement_will_decrease()) { | |
658 set_change_old_gen_for_min_pauses(decrease_old_gen_for_min_pauses_true); | |
659 *desired_promo_size_ptr = | |
660 _promo_size - promo_decrement_aligned_down(*desired_promo_size_ptr); | |
661 } else { | |
662 set_change_old_gen_for_min_pauses(increase_old_gen_for_min_pauses_true); | |
663 size_t promo_heap_delta = | |
664 promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr); | |
665 if ((*desired_promo_size_ptr + promo_heap_delta) > | |
666 *desired_promo_size_ptr) { | |
667 *desired_promo_size_ptr = | |
668 _promo_size + promo_heap_delta; | |
669 } | |
670 } | |
671 } | |
672 } | |
673 } | |
674 | |
675 void PSAdaptiveSizePolicy::adjust_eden_for_minor_pause_time(bool is_full_gc, | |
676 size_t* desired_eden_size_ptr) { | |
495 | 677 |
496 // Adjust the young generation size to reduce pause time of | 678 // Adjust the young generation size to reduce pause time of |
497 // of collections. | 679 // of collections. |
498 // | 680 // |
499 // The AdaptiveSizePolicyInitializingSteps test is not used | 681 // The AdaptiveSizePolicyInitializingSteps test is not used |
510 // Only record that the estimator indicated such an action. | 692 // Only record that the estimator indicated such an action. |
511 // *desired_eden_size_ptr = *desired_eden_size_ptr + eden_heap_delta; | 693 // *desired_eden_size_ptr = *desired_eden_size_ptr + eden_heap_delta; |
512 set_change_young_gen_for_min_pauses( | 694 set_change_young_gen_for_min_pauses( |
513 increase_young_gen_for_min_pauses_true); | 695 increase_young_gen_for_min_pauses_true); |
514 } | 696 } |
515 if (PSAdjustTenuredGenForMinorPause) { | 697 } |
516 // If the desired eden size is as small as it will get, | 698 |
517 // try to adjust the old gen size. | 699 void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(bool is_full_gc, |
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 } | |
540 | |
541 void PSAdaptiveSizePolicy::adjust_for_pause_time(bool is_full_gc, | |
542 size_t* desired_promo_size_ptr, | 700 size_t* desired_promo_size_ptr, |
543 size_t* desired_eden_size_ptr) { | 701 size_t* desired_eden_size_ptr) { |
544 | 702 |
545 size_t promo_heap_delta = 0; | 703 size_t promo_heap_delta = 0; |
546 size_t eden_heap_delta = 0; | 704 // Add some checks for a threshold for a change. For example, |
547 // Add some checks for a threshhold for a change. For example, | |
548 // a change less than the required alignment is probably not worth | 705 // a change less than the required alignment is probably not worth |
549 // attempting. | 706 // attempting. |
550 if (is_full_gc) { | |
551 set_decide_at_full_gc(decide_at_full_gc_true); | |
552 } | |
553 | 707 |
554 if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) { | 708 if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) { |
555 adjust_for_minor_pause_time(is_full_gc, | 709 adjust_promo_for_minor_pause_time(is_full_gc, desired_promo_size_ptr, desired_eden_size_ptr); |
556 desired_promo_size_ptr, | |
557 desired_eden_size_ptr); | |
558 // major pause adjustments | 710 // major pause adjustments |
559 } else if (is_full_gc) { | 711 } else if (is_full_gc) { |
560 // Adjust for the major pause time only at full gc's because the | 712 // 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. | 713 // affects of a change can only be seen at full gc's. |
562 | 714 |
571 // Only record that the estimator indicated such an action. | 723 // Only record that the estimator indicated such an action. |
572 // *desired_promo_size_ptr = _promo_size + | 724 // *desired_promo_size_ptr = _promo_size + |
573 // promo_increment_aligned_up(*desired_promo_size_ptr); | 725 // promo_increment_aligned_up(*desired_promo_size_ptr); |
574 set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true); | 726 set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true); |
575 } | 727 } |
728 } | |
729 | |
730 if (PrintAdaptiveSizePolicy && Verbose) { | |
731 gclog_or_tty->print_cr( | |
732 "PSAdaptiveSizePolicy::compute_old_gen_free_space " | |
733 "adjusting gen sizes for major pause (avg %f goal %f). " | |
734 "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT, | |
735 _avg_major_pause->average(), gc_pause_goal_sec(), | |
736 *desired_promo_size_ptr, promo_heap_delta); | |
737 } | |
738 } | |
739 | |
740 void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc, | |
741 size_t* desired_promo_size_ptr, | |
742 size_t* desired_eden_size_ptr) { | |
743 | |
744 size_t eden_heap_delta = 0; | |
745 // Add some checks for a threshold for a change. For example, | |
746 // a change less than the required alignment is probably not worth | |
747 // attempting. | |
748 if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) { | |
749 adjust_eden_for_minor_pause_time(is_full_gc, | |
750 desired_eden_size_ptr); | |
751 // major pause adjustments | |
752 } else if (is_full_gc) { | |
753 // Adjust for the major pause time only at full gc's because the | |
754 // affects of a change can only be seen at full gc's. | |
576 if (PSAdjustYoungGenForMajorPause) { | 755 if (PSAdjustYoungGenForMajorPause) { |
577 // If the promo size is at the minimum (i.e., the old gen | 756 // If the promo size is at the minimum (i.e., the old gen |
578 // size will not actually decrease), consider changing the | 757 // size will not actually decrease), consider changing the |
579 // young gen size. | 758 // young gen size. |
580 if (*desired_promo_size_ptr < _intra_generation_alignment) { | 759 if (*desired_promo_size_ptr < _intra_generation_alignment) { |
605 } | 784 } |
606 } | 785 } |
607 | 786 |
608 if (PrintAdaptiveSizePolicy && Verbose) { | 787 if (PrintAdaptiveSizePolicy && Verbose) { |
609 gclog_or_tty->print_cr( | 788 gclog_or_tty->print_cr( |
610 "AdaptiveSizePolicy::compute_generation_free_space " | 789 "PSAdaptiveSizePolicy::compute_eden_space_size " |
611 "adjusting gen sizes for major pause (avg %f goal %f). " | 790 "adjusting gen sizes for major pause (avg %f goal %f). " |
612 "desired_promo_size " SIZE_FORMAT "desired_eden_size " | 791 "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT, |
613 SIZE_FORMAT | |
614 " promo delta " SIZE_FORMAT " eden delta " SIZE_FORMAT, | |
615 _avg_major_pause->average(), gc_pause_goal_sec(), | 792 _avg_major_pause->average(), gc_pause_goal_sec(), |
616 *desired_promo_size_ptr, *desired_eden_size_ptr, | 793 *desired_eden_size_ptr, eden_heap_delta); |
617 promo_heap_delta, eden_heap_delta); | 794 } |
618 } | 795 } |
619 } | 796 |
620 | 797 void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc, |
621 void PSAdaptiveSizePolicy::adjust_for_throughput(bool is_full_gc, | 798 size_t* desired_promo_size_ptr) { |
622 size_t* desired_promo_size_ptr, | 799 |
623 size_t* desired_eden_size_ptr) { | 800 // Add some checks for a threshold for a change. For example, |
624 | |
625 // Add some checks for a threshhold for a change. For example, | |
626 // a change less than the required alignment is probably not worth | 801 // a change less than the required alignment is probably not worth |
627 // attempting. | 802 // attempting. |
628 if (is_full_gc) { | |
629 set_decide_at_full_gc(decide_at_full_gc_true); | |
630 } | |
631 | 803 |
632 if ((gc_cost() + mutator_cost()) == 0.0) { | 804 if ((gc_cost() + mutator_cost()) == 0.0) { |
633 return; | 805 return; |
634 } | 806 } |
635 | 807 |
636 if (PrintAdaptiveSizePolicy && Verbose) { | 808 if (PrintAdaptiveSizePolicy && Verbose) { |
637 gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_for_throughput(" | 809 gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_promo_for_throughput(" |
638 "is_full: %d, promo: " SIZE_FORMAT ", cur_eden: " SIZE_FORMAT "): ", | 810 "is_full: %d, promo: " SIZE_FORMAT "): ", |
639 is_full_gc, *desired_promo_size_ptr, *desired_eden_size_ptr); | 811 is_full_gc, *desired_promo_size_ptr); |
640 gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f " | 812 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()); | 813 "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost()); |
642 } | 814 } |
643 | 815 |
644 // Tenured generation | 816 // Tenured generation |
645 if (is_full_gc) { | 817 if (is_full_gc) { |
646 | |
647 // Calculate the change to use for the tenured gen. | 818 // Calculate the change to use for the tenured gen. |
648 size_t scaled_promo_heap_delta = 0; | 819 size_t scaled_promo_heap_delta = 0; |
649 // Can the increment to the generation be scaled? | 820 // Can the increment to the generation be scaled? |
650 if (gc_cost() >= 0.0 && major_gc_cost() >= 0.0) { | 821 if (gc_cost() >= 0.0 && major_gc_cost() >= 0.0) { |
651 size_t promo_heap_delta = | 822 size_t promo_heap_delta = |
717 "adjusting tenured gen for throughput (avg %f goal %f). " | 888 "adjusting tenured gen for throughput (avg %f goal %f). " |
718 "desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT , | 889 "desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT , |
719 mutator_cost(), _throughput_goal, | 890 mutator_cost(), _throughput_goal, |
720 *desired_promo_size_ptr, scaled_promo_heap_delta); | 891 *desired_promo_size_ptr, scaled_promo_heap_delta); |
721 } | 892 } |
893 } | |
894 } | |
895 | |
896 void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc, | |
897 size_t* desired_eden_size_ptr) { | |
898 | |
899 // Add some checks for a threshold for a change. For example, | |
900 // a change less than the required alignment is probably not worth | |
901 // attempting. | |
902 | |
903 if ((gc_cost() + mutator_cost()) == 0.0) { | |
904 return; | |
905 } | |
906 | |
907 if (PrintAdaptiveSizePolicy && Verbose) { | |
908 gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_eden_for_throughput(" | |
909 "is_full: %d, cur_eden: " SIZE_FORMAT "): ", | |
910 is_full_gc, *desired_eden_size_ptr); | |
911 gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f " | |
912 "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost()); | |
722 } | 913 } |
723 | 914 |
724 // Young generation | 915 // Young generation |
725 size_t scaled_eden_heap_delta = 0; | 916 size_t scaled_eden_heap_delta = 0; |
726 // Can the increment to the generation be scaled? | 917 // Can the increment to the generation be scaled? |