Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 3919:4f41766176cf
7084509: G1: fix inconsistencies and mistakes in the young list target length calculations
Summary: Fixed inconsistencies and mistakes in the young list target length calculations so that a) the calculated target length is optimal (before, it was not), b) other parameters like max survivor size and max gc locker eden expansion are always consistent with the calculated target length (before, they were not always), and c) the resulting target length was always bound by desired min and max values (before, it was not).
Reviewed-by: brutisso, johnc
author | tonyp |
---|---|
date | Thu, 08 Sep 2011 05:16:49 -0400 |
parents | 20213c8a3c40 |
children | af2ab04e0038 |
comparison
equal
deleted
inserted
replaced
3918:a6128a8ed624 | 3919:4f41766176cf |
---|---|
412 // start conservatively (around 50ms is about right) | 412 // start conservatively (around 50ms is about right) |
413 _concurrent_mark_remark_times_ms->add(0.05); | 413 _concurrent_mark_remark_times_ms->add(0.05); |
414 _concurrent_mark_cleanup_times_ms->add(0.20); | 414 _concurrent_mark_cleanup_times_ms->add(0.20); |
415 _tenuring_threshold = MaxTenuringThreshold; | 415 _tenuring_threshold = MaxTenuringThreshold; |
416 // _max_survivor_regions will be calculated by | 416 // _max_survivor_regions will be calculated by |
417 // calculate_young_list_target_length() during initialization. | 417 // update_young_list_target_length() during initialization. |
418 _max_survivor_regions = 0; | 418 _max_survivor_regions = 0; |
419 | 419 |
420 assert(GCTimeRatio > 0, | 420 assert(GCTimeRatio > 0, |
421 "we should have set it to a default value set_g1_gc_flags() " | 421 "we should have set it to a default value set_g1_gc_flags() " |
422 "if a user set it to 0"); | 422 "if a user set it to 0"); |
423 _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio)); | 423 _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio)); |
424 | |
425 uintx reserve_perc = G1ReservePercent; | |
426 // Put an artificial ceiling on this so that it's not set to a silly value. | |
427 if (reserve_perc > 50) { | |
428 reserve_perc = 50; | |
429 warning("G1ReservePercent is set to a value that is too large, " | |
430 "it's been updated to %u", reserve_perc); | |
431 } | |
432 _reserve_factor = (double) reserve_perc / 100.0; | |
433 // This will be set in calculate_reserve() when the heap is expanded | |
434 // for the first time during initialization. | |
435 _reserve_regions = 0; | |
424 | 436 |
425 initialize_all(); | 437 initialize_all(); |
426 } | 438 } |
427 | 439 |
428 // Increment "i", mod "len" | 440 // Increment "i", mod "len" |
484 } else { | 496 } else { |
485 set_adaptive_young_list_length(false); | 497 set_adaptive_young_list_length(false); |
486 _young_list_fixed_length = initial_region_num; | 498 _young_list_fixed_length = initial_region_num; |
487 } | 499 } |
488 _free_regions_at_end_of_collection = _g1->free_regions(); | 500 _free_regions_at_end_of_collection = _g1->free_regions(); |
489 calculate_young_list_min_length(); | 501 update_young_list_target_length(); |
490 guarantee( _young_list_min_length == 0, "invariant, not enough info" ); | |
491 calculate_young_list_target_length(); | |
492 | 502 |
493 // We may immediately start allocating regions and placing them on the | 503 // We may immediately start allocating regions and placing them on the |
494 // collection set list. Initialize the per-collection set info | 504 // collection set list. Initialize the per-collection set info |
495 start_incremental_cset_building(); | 505 start_incremental_cset_building(); |
496 } | 506 } |
497 | 507 |
498 // Create the jstat counters for the policy. | 508 // Create the jstat counters for the policy. |
499 void G1CollectorPolicy::initialize_gc_policy_counters() | 509 void G1CollectorPolicy::initialize_gc_policy_counters() { |
500 { | |
501 _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3); | 510 _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3); |
502 } | 511 } |
503 | 512 |
504 void G1CollectorPolicy::calculate_young_list_min_length() { | 513 bool G1CollectorPolicy::predict_will_fit(size_t young_length, |
505 _young_list_min_length = 0; | 514 double base_time_ms, |
506 | 515 size_t base_free_regions, |
507 if (!adaptive_young_list_length()) | 516 double target_pause_time_ms) { |
508 return; | 517 if (young_length >= base_free_regions) { |
509 | |
510 if (_alloc_rate_ms_seq->num() > 3) { | |
511 double now_sec = os::elapsedTime(); | |
512 double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; | |
513 double alloc_rate_ms = predict_alloc_rate_ms(); | |
514 size_t min_regions = (size_t) ceil(alloc_rate_ms * when_ms); | |
515 size_t current_region_num = _g1->young_list()->length(); | |
516 _young_list_min_length = min_regions + current_region_num; | |
517 } | |
518 } | |
519 | |
520 void G1CollectorPolicy::calculate_young_list_target_length() { | |
521 if (adaptive_young_list_length()) { | |
522 size_t rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq); | |
523 calculate_young_list_target_length(rs_lengths); | |
524 } else { | |
525 if (full_young_gcs()) | |
526 _young_list_target_length = _young_list_fixed_length; | |
527 else | |
528 _young_list_target_length = _young_list_fixed_length / 2; | |
529 } | |
530 | |
531 // Make sure we allow the application to allocate at least one | |
532 // region before we need to do a collection again. | |
533 size_t min_length = _g1->young_list()->length() + 1; | |
534 _young_list_target_length = MAX2(_young_list_target_length, min_length); | |
535 calculate_max_gc_locker_expansion(); | |
536 calculate_survivors_policy(); | |
537 } | |
538 | |
539 void G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths) { | |
540 guarantee( adaptive_young_list_length(), "pre-condition" ); | |
541 guarantee( !_in_marking_window || !_last_full_young_gc, "invariant" ); | |
542 | |
543 double start_time_sec = os::elapsedTime(); | |
544 size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1ReservePercent); | |
545 min_reserve_perc = MIN2((size_t) 50, min_reserve_perc); | |
546 size_t reserve_regions = | |
547 (size_t) ((double) min_reserve_perc * (double) _g1->n_regions() / 100.0); | |
548 | |
549 if (full_young_gcs() && _free_regions_at_end_of_collection > 0) { | |
550 // we are in fully-young mode and there are free regions in the heap | |
551 | |
552 double survivor_regions_evac_time = | |
553 predict_survivor_regions_evac_time(); | |
554 | |
555 double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; | |
556 size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq); | |
557 size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff(); | |
558 size_t scanned_cards = predict_young_card_num(adj_rs_lengths); | |
559 double base_time_ms = predict_base_elapsed_time_ms(pending_cards, scanned_cards) | |
560 + survivor_regions_evac_time; | |
561 | |
562 // the result | |
563 size_t final_young_length = 0; | |
564 | |
565 size_t init_free_regions = | |
566 MAX2((size_t)0, _free_regions_at_end_of_collection - reserve_regions); | |
567 | |
568 // if we're still under the pause target... | |
569 if (base_time_ms <= target_pause_time_ms) { | |
570 // We make sure that the shortest young length that makes sense | |
571 // fits within the target pause time. | |
572 size_t min_young_length = 1; | |
573 | |
574 if (predict_will_fit(min_young_length, base_time_ms, | |
575 init_free_regions, target_pause_time_ms)) { | |
576 // The shortest young length will fit within the target pause time; | |
577 // we'll now check whether the absolute maximum number of young | |
578 // regions will fit in the target pause time. If not, we'll do | |
579 // a binary search between min_young_length and max_young_length | |
580 size_t abs_max_young_length = _free_regions_at_end_of_collection - 1; | |
581 size_t max_young_length = abs_max_young_length; | |
582 | |
583 if (max_young_length > min_young_length) { | |
584 // Let's check if the initial max young length will fit within the | |
585 // target pause. If so then there is no need to search for a maximal | |
586 // young length - we'll return the initial maximum | |
587 | |
588 if (predict_will_fit(max_young_length, base_time_ms, | |
589 init_free_regions, target_pause_time_ms)) { | |
590 // The maximum young length will satisfy the target pause time. | |
591 // We are done so set min young length to this maximum length. | |
592 // The code after the loop will then set final_young_length using | |
593 // the value cached in the minimum length. | |
594 min_young_length = max_young_length; | |
595 } else { | |
596 // The maximum possible number of young regions will not fit within | |
597 // the target pause time so let's search.... | |
598 | |
599 size_t diff = (max_young_length - min_young_length) / 2; | |
600 max_young_length = min_young_length + diff; | |
601 | |
602 while (max_young_length > min_young_length) { | |
603 if (predict_will_fit(max_young_length, base_time_ms, | |
604 init_free_regions, target_pause_time_ms)) { | |
605 | |
606 // The current max young length will fit within the target | |
607 // pause time. Note we do not exit the loop here. By setting | |
608 // min = max, and then increasing the max below means that | |
609 // we will continue searching for an upper bound in the | |
610 // range [max..max+diff] | |
611 min_young_length = max_young_length; | |
612 } | |
613 diff = (max_young_length - min_young_length) / 2; | |
614 max_young_length = min_young_length + diff; | |
615 } | |
616 // the above loop found a maximal young length that will fit | |
617 // within the target pause time. | |
618 } | |
619 assert(min_young_length <= abs_max_young_length, "just checking"); | |
620 } | |
621 final_young_length = min_young_length; | |
622 } | |
623 } | |
624 // and we're done! | |
625 | |
626 // we should have at least one region in the target young length | |
627 _young_list_target_length = | |
628 final_young_length + _recorded_survivor_regions; | |
629 | |
630 // let's keep an eye of how long we spend on this calculation | |
631 // right now, I assume that we'll print it when we need it; we | |
632 // should really adde it to the breakdown of a pause | |
633 double end_time_sec = os::elapsedTime(); | |
634 double elapsed_time_ms = (end_time_sec - start_time_sec) * 1000.0; | |
635 | |
636 #ifdef TRACE_CALC_YOUNG_LENGTH | |
637 // leave this in for debugging, just in case | |
638 gclog_or_tty->print_cr("target = %1.1lf ms, young = " SIZE_FORMAT ", " | |
639 "elapsed %1.2lf ms, (%s%s) " SIZE_FORMAT SIZE_FORMAT, | |
640 target_pause_time_ms, | |
641 _young_list_target_length | |
642 elapsed_time_ms, | |
643 full_young_gcs() ? "full" : "partial", | |
644 during_initial_mark_pause() ? " i-m" : "", | |
645 _in_marking_window, | |
646 _in_marking_window_im); | |
647 #endif // TRACE_CALC_YOUNG_LENGTH | |
648 | |
649 if (_young_list_target_length < _young_list_min_length) { | |
650 // bummer; this means that, if we do a pause when the maximal | |
651 // length dictates, we'll violate the pause spacing target (the | |
652 // min length was calculate based on the application's current | |
653 // alloc rate); | |
654 | |
655 // so, we have to bite the bullet, and allocate the minimum | |
656 // number. We'll violate our target, but we just can't meet it. | |
657 | |
658 #ifdef TRACE_CALC_YOUNG_LENGTH | |
659 // leave this in for debugging, just in case | |
660 gclog_or_tty->print_cr("adjusted target length from " | |
661 SIZE_FORMAT " to " SIZE_FORMAT, | |
662 _young_list_target_length, _young_list_min_length); | |
663 #endif // TRACE_CALC_YOUNG_LENGTH | |
664 | |
665 _young_list_target_length = _young_list_min_length; | |
666 } | |
667 } else { | |
668 // we are in a partially-young mode or we've run out of regions (due | |
669 // to evacuation failure) | |
670 | |
671 #ifdef TRACE_CALC_YOUNG_LENGTH | |
672 // leave this in for debugging, just in case | |
673 gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT | |
674 _young_list_min_length); | |
675 #endif // TRACE_CALC_YOUNG_LENGTH | |
676 // we'll do the pause as soon as possible by choosing the minimum | |
677 _young_list_target_length = _young_list_min_length; | |
678 } | |
679 | |
680 _rs_lengths_prediction = rs_lengths; | |
681 } | |
682 | |
683 // This is used by: calculate_young_list_target_length(rs_length). It | |
684 // returns true iff: | |
685 // the predicted pause time for the given young list will not overflow | |
686 // the target pause time | |
687 // and: | |
688 // the predicted amount of surviving data will not overflow the | |
689 // the amount of free space available for survivor regions. | |
690 // | |
691 bool | |
692 G1CollectorPolicy::predict_will_fit(size_t young_length, | |
693 double base_time_ms, | |
694 size_t init_free_regions, | |
695 double target_pause_time_ms) { | |
696 | |
697 if (young_length >= init_free_regions) | |
698 // end condition 1: not enough space for the young regions | 518 // end condition 1: not enough space for the young regions |
699 return false; | 519 return false; |
700 | 520 } |
701 double accum_surv_rate_adj = 0.0; | 521 |
702 double accum_surv_rate = | 522 double accum_surv_rate = accum_yg_surv_rate_pred((int)(young_length - 1)); |
703 accum_yg_surv_rate_pred((int)(young_length - 1)) - accum_surv_rate_adj; | |
704 | |
705 size_t bytes_to_copy = | 523 size_t bytes_to_copy = |
706 (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes); | 524 (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes); |
707 | |
708 double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy); | 525 double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy); |
709 | 526 double young_other_time_ms = predict_young_other_time_ms(young_length); |
710 double young_other_time_ms = | 527 double pause_time_ms = base_time_ms + copy_time_ms + young_other_time_ms; |
711 predict_young_other_time_ms(young_length); | 528 if (pause_time_ms > target_pause_time_ms) { |
712 | 529 // end condition 2: prediction is over the target pause time |
713 double pause_time_ms = | |
714 base_time_ms + copy_time_ms + young_other_time_ms; | |
715 | |
716 if (pause_time_ms > target_pause_time_ms) | |
717 // end condition 2: over the target pause time | |
718 return false; | 530 return false; |
531 } | |
719 | 532 |
720 size_t free_bytes = | 533 size_t free_bytes = |
721 (init_free_regions - young_length) * HeapRegion::GrainBytes; | 534 (base_free_regions - young_length) * HeapRegion::GrainBytes; |
722 | 535 if ((2.0 * sigma()) * (double) bytes_to_copy > (double) free_bytes) { |
723 if ((2.0 + sigma()) * (double) bytes_to_copy > (double) free_bytes) | 536 // end condition 3: out-of-space (conservatively!) |
724 // end condition 3: out of to-space (conservatively) | |
725 return false; | 537 return false; |
538 } | |
726 | 539 |
727 // success! | 540 // success! |
728 return true; | 541 return true; |
542 } | |
543 | |
544 void G1CollectorPolicy::calculate_reserve(size_t all_regions) { | |
545 double reserve_regions_d = (double) all_regions * _reserve_factor; | |
546 // We use ceiling so that if reserve_regions_d is > 0.0 (but | |
547 // smaller than 1.0) we'll get 1. | |
548 _reserve_regions = (size_t) ceil(reserve_regions_d); | |
549 } | |
550 | |
551 size_t G1CollectorPolicy::calculate_young_list_desired_min_length( | |
552 size_t base_min_length) { | |
553 size_t desired_min_length = 0; | |
554 if (adaptive_young_list_length()) { | |
555 if (_alloc_rate_ms_seq->num() > 3) { | |
556 double now_sec = os::elapsedTime(); | |
557 double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; | |
558 double alloc_rate_ms = predict_alloc_rate_ms(); | |
559 desired_min_length = (size_t) ceil(alloc_rate_ms * when_ms); | |
560 } else { | |
561 // otherwise we don't have enough info to make the prediction | |
562 } | |
563 } | |
564 // Here, we might want to also take into account any additional | |
565 // constraints (i.e., user-defined minimum bound). Currently, we don't. | |
566 return base_min_length + desired_min_length; | |
567 } | |
568 | |
569 size_t G1CollectorPolicy::calculate_young_list_desired_max_length() { | |
570 // Here, we might want to also take into account any additional | |
571 // constraints (i.e., user-defined minimum bound). Currently, we | |
572 // effectively don't set this bound. | |
573 return _g1->n_regions(); | |
574 } | |
575 | |
576 void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) { | |
577 if (rs_lengths == (size_t) -1) { | |
578 // if it's set to the default value (-1), we should predict it; | |
579 // otherwise, use the given value. | |
580 rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq); | |
581 } | |
582 | |
583 // Calculate the absolute and desired min bounds. | |
584 | |
585 // This is how many young regions we already have (currently: the survivors). | |
586 size_t base_min_length = recorded_survivor_regions(); | |
587 // This is the absolute minimum young length, which ensures that we | |
588 // can allocate one eden region in the worst-case. | |
589 size_t absolute_min_length = base_min_length + 1; | |
590 size_t desired_min_length = | |
591 calculate_young_list_desired_min_length(base_min_length); | |
592 if (desired_min_length < absolute_min_length) { | |
593 desired_min_length = absolute_min_length; | |
594 } | |
595 | |
596 // Calculate the absolute and desired max bounds. | |
597 | |
598 // We will try our best not to "eat" into the reserve. | |
599 size_t absolute_max_length = 0; | |
600 if (_free_regions_at_end_of_collection > _reserve_regions) { | |
601 absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions; | |
602 } | |
603 size_t desired_max_length = calculate_young_list_desired_max_length(); | |
604 if (desired_max_length > absolute_max_length) { | |
605 desired_max_length = absolute_max_length; | |
606 } | |
607 | |
608 size_t young_list_target_length = 0; | |
609 if (adaptive_young_list_length()) { | |
610 if (full_young_gcs()) { | |
611 young_list_target_length = | |
612 calculate_young_list_target_length(rs_lengths, | |
613 base_min_length, | |
614 desired_min_length, | |
615 desired_max_length); | |
616 _rs_lengths_prediction = rs_lengths; | |
617 } else { | |
618 // Don't calculate anything and let the code below bound it to | |
619 // the desired_min_length, i.e., do the next GC as soon as | |
620 // possible to maximize how many old regions we can add to it. | |
621 } | |
622 } else { | |
623 if (full_young_gcs()) { | |
624 young_list_target_length = _young_list_fixed_length; | |
625 } else { | |
626 // A bit arbitrary: during partially-young GCs we allocate half | |
627 // the young regions to try to add old regions to the CSet. | |
628 young_list_target_length = _young_list_fixed_length / 2; | |
629 // We choose to accept that we might go under the desired min | |
630 // length given that we intentionally ask for a smaller young gen. | |
631 desired_min_length = absolute_min_length; | |
632 } | |
633 } | |
634 | |
635 // Make sure we don't go over the desired max length, nor under the | |
636 // desired min length. In case they clash, desired_min_length wins | |
637 // which is why that test is second. | |
638 if (young_list_target_length > desired_max_length) { | |
639 young_list_target_length = desired_max_length; | |
640 } | |
641 if (young_list_target_length < desired_min_length) { | |
642 young_list_target_length = desired_min_length; | |
643 } | |
644 | |
645 assert(young_list_target_length > recorded_survivor_regions(), | |
646 "we should be able to allocate at least one eden region"); | |
647 assert(young_list_target_length >= absolute_min_length, "post-condition"); | |
648 _young_list_target_length = young_list_target_length; | |
649 | |
650 update_max_gc_locker_expansion(); | |
651 } | |
652 | |
653 size_t | |
654 G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths, | |
655 size_t base_min_length, | |
656 size_t desired_min_length, | |
657 size_t desired_max_length) { | |
658 assert(adaptive_young_list_length(), "pre-condition"); | |
659 assert(full_young_gcs(), "only call this for fully-young GCs"); | |
660 | |
661 // In case some edge-condition makes the desired max length too small... | |
662 if (desired_max_length <= desired_min_length) { | |
663 return desired_min_length; | |
664 } | |
665 | |
666 // We'll adjust min_young_length and max_young_length not to include | |
667 // the already allocated young regions (i.e., so they reflect the | |
668 // min and max eden regions we'll allocate). The base_min_length | |
669 // will be reflected in the predictions by the | |
670 // survivor_regions_evac_time prediction. | |
671 assert(desired_min_length > base_min_length, "invariant"); | |
672 size_t min_young_length = desired_min_length - base_min_length; | |
673 assert(desired_max_length > base_min_length, "invariant"); | |
674 size_t max_young_length = desired_max_length - base_min_length; | |
675 | |
676 double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; | |
677 double survivor_regions_evac_time = predict_survivor_regions_evac_time(); | |
678 size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq); | |
679 size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff(); | |
680 size_t scanned_cards = predict_young_card_num(adj_rs_lengths); | |
681 double base_time_ms = | |
682 predict_base_elapsed_time_ms(pending_cards, scanned_cards) + | |
683 survivor_regions_evac_time; | |
684 size_t available_free_regions = _free_regions_at_end_of_collection; | |
685 size_t base_free_regions = 0; | |
686 if (available_free_regions > _reserve_regions) { | |
687 base_free_regions = available_free_regions - _reserve_regions; | |
688 } | |
689 | |
690 // Here, we will make sure that the shortest young length that | |
691 // makes sense fits within the target pause time. | |
692 | |
693 if (predict_will_fit(min_young_length, base_time_ms, | |
694 base_free_regions, target_pause_time_ms)) { | |
695 // The shortest young length will fit into the target pause time; | |
696 // we'll now check whether the absolute maximum number of young | |
697 // regions will fit in the target pause time. If not, we'll do | |
698 // a binary search between min_young_length and max_young_length. | |
699 if (predict_will_fit(max_young_length, base_time_ms, | |
700 base_free_regions, target_pause_time_ms)) { | |
701 // The maximum young length will fit into the target pause time. | |
702 // We are done so set min young length to the maximum length (as | |
703 // the result is assumed to be returned in min_young_length). | |
704 min_young_length = max_young_length; | |
705 } else { | |
706 // The maximum possible number of young regions will not fit within | |
707 // the target pause time so we'll search for the optimal | |
708 // length. The loop invariants are: | |
709 // | |
710 // min_young_length < max_young_length | |
711 // min_young_length is known to fit into the target pause time | |
712 // max_young_length is known not to fit into the target pause time | |
713 // | |
714 // Going into the loop we know the above hold as we've just | |
715 // checked them. Every time around the loop we check whether | |
716 // the middle value between min_young_length and | |
717 // max_young_length fits into the target pause time. If it | |
718 // does, it becomes the new min. If it doesn't, it becomes | |
719 // the new max. This way we maintain the loop invariants. | |
720 | |
721 assert(min_young_length < max_young_length, "invariant"); | |
722 size_t diff = (max_young_length - min_young_length) / 2; | |
723 while (diff > 0) { | |
724 size_t young_length = min_young_length + diff; | |
725 if (predict_will_fit(young_length, base_time_ms, | |
726 base_free_regions, target_pause_time_ms)) { | |
727 min_young_length = young_length; | |
728 } else { | |
729 max_young_length = young_length; | |
730 } | |
731 assert(min_young_length < max_young_length, "invariant"); | |
732 diff = (max_young_length - min_young_length) / 2; | |
733 } | |
734 // The results is min_young_length which, according to the | |
735 // loop invariants, should fit within the target pause time. | |
736 | |
737 // These are the post-conditions of the binary search above: | |
738 assert(min_young_length < max_young_length, | |
739 "otherwise we should have discovered that max_young_length " | |
740 "fits into the pause target and not done the binary search"); | |
741 assert(predict_will_fit(min_young_length, base_time_ms, | |
742 base_free_regions, target_pause_time_ms), | |
743 "min_young_length, the result of the binary search, should " | |
744 "fit into the pause target"); | |
745 assert(!predict_will_fit(min_young_length + 1, base_time_ms, | |
746 base_free_regions, target_pause_time_ms), | |
747 "min_young_length, the result of the binary search, should be " | |
748 "optimal, so no larger length should fit into the pause target"); | |
749 } | |
750 } else { | |
751 // Even the minimum length doesn't fit into the pause time | |
752 // target, return it as the result nevertheless. | |
753 } | |
754 return base_min_length + min_young_length; | |
729 } | 755 } |
730 | 756 |
731 double G1CollectorPolicy::predict_survivor_regions_evac_time() { | 757 double G1CollectorPolicy::predict_survivor_regions_evac_time() { |
732 double survivor_regions_evac_time = 0.0; | 758 double survivor_regions_evac_time = 0.0; |
733 for (HeapRegion * r = _recorded_survivor_head; | 759 for (HeapRegion * r = _recorded_survivor_head; |
736 survivor_regions_evac_time += predict_region_elapsed_time_ms(r, true); | 762 survivor_regions_evac_time += predict_region_elapsed_time_ms(r, true); |
737 } | 763 } |
738 return survivor_regions_evac_time; | 764 return survivor_regions_evac_time; |
739 } | 765 } |
740 | 766 |
741 void G1CollectorPolicy::check_prediction_validity() { | 767 void G1CollectorPolicy::revise_young_list_target_length_if_necessary() { |
742 guarantee( adaptive_young_list_length(), "should not call this otherwise" ); | 768 guarantee( adaptive_young_list_length(), "should not call this otherwise" ); |
743 | 769 |
744 size_t rs_lengths = _g1->young_list()->sampled_rs_lengths(); | 770 size_t rs_lengths = _g1->young_list()->sampled_rs_lengths(); |
745 if (rs_lengths > _rs_lengths_prediction) { | 771 if (rs_lengths > _rs_lengths_prediction) { |
746 // add 10% to avoid having to recalculate often | 772 // add 10% to avoid having to recalculate often |
747 size_t rs_lengths_prediction = rs_lengths * 1100 / 1000; | 773 size_t rs_lengths_prediction = rs_lengths * 1100 / 1000; |
748 calculate_young_list_target_length(rs_lengths_prediction); | 774 update_young_list_target_length(rs_lengths_prediction); |
749 } | 775 } |
750 } | 776 } |
777 | |
778 | |
751 | 779 |
752 HeapWord* G1CollectorPolicy::mem_allocate_work(size_t size, | 780 HeapWord* G1CollectorPolicy::mem_allocate_work(size_t size, |
753 bool is_tlab, | 781 bool is_tlab, |
754 bool* gc_overhead_limit_was_exceeded) { | 782 bool* gc_overhead_limit_was_exceeded) { |
755 guarantee(false, "Not using this policy feature yet."); | 783 guarantee(false, "Not using this policy feature yet."); |
853 _prev_region_num_tenured = _region_num_tenured; | 881 _prev_region_num_tenured = _region_num_tenured; |
854 | 882 |
855 _free_regions_at_end_of_collection = _g1->free_regions(); | 883 _free_regions_at_end_of_collection = _g1->free_regions(); |
856 // Reset survivors SurvRateGroup. | 884 // Reset survivors SurvRateGroup. |
857 _survivor_surv_rate_group->reset(); | 885 _survivor_surv_rate_group->reset(); |
858 calculate_young_list_min_length(); | 886 update_young_list_target_length(); |
859 calculate_young_list_target_length(); | |
860 } | 887 } |
861 | 888 |
862 void G1CollectorPolicy::record_stop_world_start() { | 889 void G1CollectorPolicy::record_stop_world_start() { |
863 _stop_world_start = os::elapsedTime(); | 890 _stop_world_start = os::elapsedTime(); |
864 } | 891 } |
868 if (PrintGCDetails) { | 895 if (PrintGCDetails) { |
869 gclog_or_tty->stamp(PrintGCTimeStamps); | 896 gclog_or_tty->stamp(PrintGCTimeStamps); |
870 gclog_or_tty->print("[GC pause"); | 897 gclog_or_tty->print("[GC pause"); |
871 gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial"); | 898 gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial"); |
872 } | 899 } |
900 | |
901 // We only need to do this here as the policy will only be applied | |
902 // to the GC we're about to start. so, no point is calculating this | |
903 // every time we calculate / recalculate the target young length. | |
904 update_survivors_policy(); | |
873 | 905 |
874 assert(_g1->used() == _g1->recalculate_used(), | 906 assert(_g1->used() == _g1->recalculate_used(), |
875 err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT, | 907 err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT, |
876 _g1->used(), _g1->recalculate_used())); | 908 _g1->used(), _g1->recalculate_used())); |
877 | 909 |
994 void | 1026 void |
995 G1CollectorPolicy::record_concurrent_mark_cleanup_completed() { | 1027 G1CollectorPolicy::record_concurrent_mark_cleanup_completed() { |
996 _should_revert_to_full_young_gcs = false; | 1028 _should_revert_to_full_young_gcs = false; |
997 _last_full_young_gc = true; | 1029 _last_full_young_gc = true; |
998 _in_marking_window = false; | 1030 _in_marking_window = false; |
999 if (adaptive_young_list_length()) | |
1000 calculate_young_list_target_length(); | |
1001 } | 1031 } |
1002 | 1032 |
1003 void G1CollectorPolicy::record_concurrent_pause() { | 1033 void G1CollectorPolicy::record_concurrent_pause() { |
1004 if (_stop_world_start > 0.0) { | 1034 if (_stop_world_start > 0.0) { |
1005 double yield_ms = (os::elapsedTime() - _stop_world_start) * 1000.0; | 1035 double yield_ms = (os::elapsedTime() - _stop_world_start) * 1000.0; |
1646 } | 1676 } |
1647 | 1677 |
1648 _in_marking_window = new_in_marking_window; | 1678 _in_marking_window = new_in_marking_window; |
1649 _in_marking_window_im = new_in_marking_window_im; | 1679 _in_marking_window_im = new_in_marking_window_im; |
1650 _free_regions_at_end_of_collection = _g1->free_regions(); | 1680 _free_regions_at_end_of_collection = _g1->free_regions(); |
1651 calculate_young_list_min_length(); | 1681 update_young_list_target_length(); |
1652 calculate_young_list_target_length(); | |
1653 | 1682 |
1654 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. | 1683 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. |
1655 double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; | 1684 double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; |
1656 adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); | 1685 adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); |
1657 // </NEW PREDICTION> | 1686 // </NEW PREDICTION> |
2322 ShouldNotReachHere(); | 2351 ShouldNotReachHere(); |
2323 return REGIONS_UNLIMITED; | 2352 return REGIONS_UNLIMITED; |
2324 }; | 2353 }; |
2325 } | 2354 } |
2326 | 2355 |
2327 void G1CollectorPolicy::calculate_max_gc_locker_expansion() { | 2356 void G1CollectorPolicy::update_max_gc_locker_expansion() { |
2328 size_t expansion_region_num = 0; | 2357 size_t expansion_region_num = 0; |
2329 if (GCLockerEdenExpansionPercent > 0) { | 2358 if (GCLockerEdenExpansionPercent > 0) { |
2330 double perc = (double) GCLockerEdenExpansionPercent / 100.0; | 2359 double perc = (double) GCLockerEdenExpansionPercent / 100.0; |
2331 double expansion_region_num_d = perc * (double) _young_list_target_length; | 2360 double expansion_region_num_d = perc * (double) _young_list_target_length; |
2332 // We use ceiling so that if expansion_region_num_d is > 0.0 (but | 2361 // We use ceiling so that if expansion_region_num_d is > 0.0 (but |
2338 _young_list_max_length = _young_list_target_length + expansion_region_num; | 2367 _young_list_max_length = _young_list_target_length + expansion_region_num; |
2339 assert(_young_list_target_length <= _young_list_max_length, "post-condition"); | 2368 assert(_young_list_target_length <= _young_list_max_length, "post-condition"); |
2340 } | 2369 } |
2341 | 2370 |
2342 // Calculates survivor space parameters. | 2371 // Calculates survivor space parameters. |
2343 void G1CollectorPolicy::calculate_survivors_policy() | 2372 void G1CollectorPolicy::update_survivors_policy() { |
2344 { | 2373 double max_survivor_regions_d = |
2345 _max_survivor_regions = _young_list_target_length / SurvivorRatio; | 2374 (double) _young_list_target_length / (double) SurvivorRatio; |
2375 // We use ceiling so that if max_survivor_regions_d is > 0.0 (but | |
2376 // smaller than 1.0) we'll get 1. | |
2377 _max_survivor_regions = (size_t) ceil(max_survivor_regions_d); | |
2378 | |
2346 _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold( | 2379 _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold( |
2347 HeapRegion::GrainWords * _max_survivor_regions); | 2380 HeapRegion::GrainWords * _max_survivor_regions); |
2348 } | 2381 } |
2349 | 2382 |
2350 #ifndef PRODUCT | 2383 #ifndef PRODUCT |