Mercurial > hg > truffle
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 } |