comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 3920:af2ab04e0038

6929868: G1: introduce min / max young gen size bounds Summary: Make G1 handle young gen size command line flags more consistently Reviewed-by: tonyp, jwilhelm
author brutisso
date Thu, 08 Sep 2011 16:29:41 +0200
parents 4f41766176cf
children f1b4e0e0bdad
comparison
equal deleted inserted replaced
3919:4f41766176cf 3920:af2ab04e0038
144 _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), 144 _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
145 _all_pause_times_ms(new NumberSeq()), 145 _all_pause_times_ms(new NumberSeq()),
146 _stop_world_start(0.0), 146 _stop_world_start(0.0),
147 _all_stop_world_times_ms(new NumberSeq()), 147 _all_stop_world_times_ms(new NumberSeq()),
148 _all_yield_times_ms(new NumberSeq()), 148 _all_yield_times_ms(new NumberSeq()),
149 _using_new_ratio_calculations(false),
149 150
150 _all_mod_union_times_ms(new NumberSeq()), 151 _all_mod_union_times_ms(new NumberSeq()),
151 152
152 _summary(new Summary()), 153 _summary(new Summary()),
153 154
428 reserve_perc = 50; 429 reserve_perc = 50;
429 warning("G1ReservePercent is set to a value that is too large, " 430 warning("G1ReservePercent is set to a value that is too large, "
430 "it's been updated to %u", reserve_perc); 431 "it's been updated to %u", reserve_perc);
431 } 432 }
432 _reserve_factor = (double) reserve_perc / 100.0; 433 _reserve_factor = (double) reserve_perc / 100.0;
433 // This will be set in calculate_reserve() when the heap is expanded 434 // This will be set when the heap is expanded
434 // for the first time during initialization. 435 // for the first time during initialization.
435 _reserve_regions = 0; 436 _reserve_regions = 0;
436 437
437 initialize_all(); 438 initialize_all();
438 } 439 }
456 // TwoGenerationCollectorPolicy class. This is similar to what 457 // TwoGenerationCollectorPolicy class. This is similar to what
457 // ParallelScavenge does with its GenerationSizer class (see 458 // ParallelScavenge does with its GenerationSizer class (see
458 // ParallelScavengeHeap::initialize()). We might change this in the 459 // ParallelScavengeHeap::initialize()). We might change this in the
459 // future, but it's a good start. 460 // future, but it's a good start.
460 class G1YoungGenSizer : public TwoGenerationCollectorPolicy { 461 class G1YoungGenSizer : public TwoGenerationCollectorPolicy {
461 size_t size_to_region_num(size_t byte_size) {
462 return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
463 }
464 462
465 public: 463 public:
466 G1YoungGenSizer() { 464 G1YoungGenSizer() {
467 initialize_flags(); 465 initialize_flags();
468 initialize_size_info(); 466 initialize_size_info();
469 } 467 }
470 468 size_t size_to_region_num(size_t byte_size) {
469 return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
470 }
471 size_t min_young_region_num() { 471 size_t min_young_region_num() {
472 return size_to_region_num(_min_gen0_size); 472 return size_to_region_num(_min_gen0_size);
473 } 473 }
474 size_t initial_young_region_num() { 474 size_t initial_young_region_num() {
475 return size_to_region_num(_initial_gen0_size); 475 return size_to_region_num(_initial_gen0_size);
476 } 476 }
477 size_t max_young_region_num() { 477 size_t max_young_region_num() {
478 return size_to_region_num(_max_gen0_size); 478 return size_to_region_num(_max_gen0_size);
479 } 479 }
480 }; 480 };
481
482 void G1CollectorPolicy::update_young_list_size_using_newratio(size_t number_of_heap_regions) {
483 assert(number_of_heap_regions > 0, "Heap must be initialized");
484 size_t young_size = number_of_heap_regions / (NewRatio + 1);
485 _min_desired_young_length = young_size;
486 _max_desired_young_length = young_size;
487 }
481 488
482 void G1CollectorPolicy::init() { 489 void G1CollectorPolicy::init() {
483 // Set aside an initial future to_space. 490 // Set aside an initial future to_space.
484 _g1 = G1CollectedHeap::heap(); 491 _g1 = G1CollectedHeap::heap();
485 492
487 494
488 initialize_gc_policy_counters(); 495 initialize_gc_policy_counters();
489 496
490 G1YoungGenSizer sizer; 497 G1YoungGenSizer sizer;
491 size_t initial_region_num = sizer.initial_young_region_num(); 498 size_t initial_region_num = sizer.initial_young_region_num();
492 499 _min_desired_young_length = sizer.min_young_region_num();
493 if (UseAdaptiveSizePolicy) { 500 _max_desired_young_length = sizer.max_young_region_num();
494 set_adaptive_young_list_length(true); 501
502 if (FLAG_IS_CMDLINE(NewRatio)) {
503 if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
504 gclog_or_tty->print_cr("-XX:NewSize and -XX:MaxNewSize overrides -XX:NewRatio");
505 } else {
506 // Treat NewRatio as a fixed size that is only recalculated when the heap size changes
507 size_t heap_regions = sizer.size_to_region_num(_g1->n_regions());
508 update_young_list_size_using_newratio(heap_regions);
509 _using_new_ratio_calculations = true;
510 }
511 }
512
513 // GenCollectorPolicy guarantees that min <= initial <= max.
514 // Asserting here just to state that we rely on this property.
515 assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values");
516 assert(initial_region_num <= _max_desired_young_length, "Initial young gen size too large");
517 assert(_min_desired_young_length <= initial_region_num, "Initial young gen size too small");
518
519 set_adaptive_young_list_length(_min_desired_young_length < _max_desired_young_length);
520 if (adaptive_young_list_length()) {
495 _young_list_fixed_length = 0; 521 _young_list_fixed_length = 0;
496 } else { 522 } else {
497 set_adaptive_young_list_length(false);
498 _young_list_fixed_length = initial_region_num; 523 _young_list_fixed_length = initial_region_num;
499 } 524 }
500 _free_regions_at_end_of_collection = _g1->free_regions(); 525 _free_regions_at_end_of_collection = _g1->free_regions();
501 update_young_list_target_length(); 526 update_young_list_target_length();
527 _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes;
502 528
503 // We may immediately start allocating regions and placing them on the 529 // We may immediately start allocating regions and placing them on the
504 // collection set list. Initialize the per-collection set info 530 // collection set list. Initialize the per-collection set info
505 start_incremental_cset_building(); 531 start_incremental_cset_building();
506 } 532 }
539 565
540 // success! 566 // success!
541 return true; 567 return true;
542 } 568 }
543 569
544 void G1CollectorPolicy::calculate_reserve(size_t all_regions) { 570 void G1CollectorPolicy::record_new_heap_size(size_t new_number_of_regions) {
545 double reserve_regions_d = (double) all_regions * _reserve_factor; 571 // re-calculate the necessary reserve
572 double reserve_regions_d = (double) new_number_of_regions * _reserve_factor;
546 // We use ceiling so that if reserve_regions_d is > 0.0 (but 573 // We use ceiling so that if reserve_regions_d is > 0.0 (but
547 // smaller than 1.0) we'll get 1. 574 // smaller than 1.0) we'll get 1.
548 _reserve_regions = (size_t) ceil(reserve_regions_d); 575 _reserve_regions = (size_t) ceil(reserve_regions_d);
576
577 if (_using_new_ratio_calculations) {
578 // -XX:NewRatio was specified so we need to update the
579 // young gen length when the heap size has changed.
580 update_young_list_size_using_newratio(new_number_of_regions);
581 }
549 } 582 }
550 583
551 size_t G1CollectorPolicy::calculate_young_list_desired_min_length( 584 size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
552 size_t base_min_length) { 585 size_t base_min_length) {
553 size_t desired_min_length = 0; 586 size_t desired_min_length = 0;
559 desired_min_length = (size_t) ceil(alloc_rate_ms * when_ms); 592 desired_min_length = (size_t) ceil(alloc_rate_ms * when_ms);
560 } else { 593 } else {
561 // otherwise we don't have enough info to make the prediction 594 // otherwise we don't have enough info to make the prediction
562 } 595 }
563 } 596 }
564 // Here, we might want to also take into account any additional 597 desired_min_length += base_min_length;
565 // constraints (i.e., user-defined minimum bound). Currently, we don't. 598 // make sure we don't go below any user-defined minimum bound
566 return base_min_length + desired_min_length; 599 return MAX2(_min_desired_young_length, desired_min_length);
567 } 600 }
568 601
569 size_t G1CollectorPolicy::calculate_young_list_desired_max_length() { 602 size_t G1CollectorPolicy::calculate_young_list_desired_max_length() {
570 // Here, we might want to also take into account any additional 603 // Here, we might want to also take into account any additional
571 // constraints (i.e., user-defined minimum bound). Currently, we 604 // constraints (i.e., user-defined minimum bound). Currently, we
572 // effectively don't set this bound. 605 // effectively don't set this bound.
573 return _g1->n_regions(); 606 return _max_desired_young_length;
574 } 607 }
575 608
576 void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) { 609 void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {
577 if (rs_lengths == (size_t) -1) { 610 if (rs_lengths == (size_t) -1) {
578 // if it's set to the default value (-1), we should predict it; 611 // if it's set to the default value (-1), we should predict it;
1697 size_t eden_bytes = young_list->eden_used_bytes(); 1730 size_t eden_bytes = young_list->eden_used_bytes();
1698 size_t survivor_bytes = young_list->survivor_used_bytes(); 1731 size_t survivor_bytes = young_list->survivor_used_bytes();
1699 size_t used_before_gc = _cur_collection_pause_used_at_start_bytes; 1732 size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
1700 size_t used = _g1->used(); 1733 size_t used = _g1->used();
1701 size_t capacity = _g1->capacity(); 1734 size_t capacity = _g1->capacity();
1735 size_t eden_capacity =
1736 (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
1702 1737
1703 gclog_or_tty->print_cr( 1738 gclog_or_tty->print_cr(
1704 " [Eden: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" " 1739 " [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
1705 "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" " 1740 "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
1706 "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->" 1741 "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
1707 EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]", 1742 EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
1708 EXT_SIZE_PARAMS(_eden_bytes_before_gc), 1743 EXT_SIZE_PARAMS(_eden_bytes_before_gc),
1709 EXT_SIZE_PARAMS(eden_bytes), 1744 EXT_SIZE_PARAMS(_prev_eden_capacity),
1710 EXT_SIZE_PARAMS(_survivor_bytes_before_gc), 1745 EXT_SIZE_PARAMS(eden_bytes),
1711 EXT_SIZE_PARAMS(survivor_bytes), 1746 EXT_SIZE_PARAMS(eden_capacity),
1712 EXT_SIZE_PARAMS(used_before_gc), 1747 EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
1713 EXT_SIZE_PARAMS(_capacity_before_gc), 1748 EXT_SIZE_PARAMS(survivor_bytes),
1714 EXT_SIZE_PARAMS(used), 1749 EXT_SIZE_PARAMS(used_before_gc),
1715 EXT_SIZE_PARAMS(capacity)); 1750 EXT_SIZE_PARAMS(_capacity_before_gc),
1751 EXT_SIZE_PARAMS(used),
1752 EXT_SIZE_PARAMS(capacity));
1753
1754 _prev_eden_capacity = eden_capacity;
1716 } else if (PrintGC) { 1755 } else if (PrintGC) {
1717 _g1->print_size_transition(gclog_or_tty, 1756 _g1->print_size_transition(gclog_or_tty,
1718 _cur_collection_pause_used_at_start_bytes, 1757 _cur_collection_pause_used_at_start_bytes,
1719 _g1->used(), _g1->capacity()); 1758 _g1->used(), _g1->capacity());
1720 } 1759 }