src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp

Print this page
rev 2637 : Tony's refactoring
rev 2638 : 6929868: G1: introduce min / max young gen size bounds
Summary: Make G1 handle young gen size command line flags more consistently
Reviewed-by: tonyp

*** 143,152 **** --- 143,153 ---- _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), _all_pause_times_ms(new NumberSeq()), _stop_world_start(0.0), _all_stop_world_times_ms(new NumberSeq()), _all_yield_times_ms(new NumberSeq()), + _using_new_ratio_calculations(false), _all_mod_union_times_ms(new NumberSeq()), _summary(new Summary()),
*** 416,426 **** reserve_perc = 50; warning("G1ReservePercent is set to a value that is too large, " "it's been updated to %u", G1ReservePercent); } _reserve_factor = (double) reserve_perc / 100.0; ! // This will be set in calculate_reserve() when the heap is expanded // for the first time during initialization. _reserve_regions = 0; initialize_all(); } --- 417,427 ---- reserve_perc = 50; warning("G1ReservePercent is set to a value that is too large, " "it's been updated to %u", G1ReservePercent); } _reserve_factor = (double) reserve_perc / 100.0; ! // This will be set when the heap is expanded // for the first time during initialization. _reserve_regions = 0; initialize_all(); }
*** 465,494 **** size_t max_young_region_num() { return size_to_region_num(_max_gen0_size); } }; void G1CollectorPolicy::init() { // Set aside an initial future to_space. _g1 = G1CollectedHeap::heap(); assert(Heap_lock->owned_by_self(), "Locking discipline."); initialize_gc_policy_counters(); G1YoungGenSizer sizer; size_t initial_region_num = sizer.initial_young_region_num(); ! if (UseAdaptiveSizePolicy) { ! set_adaptive_young_list_length(true); _young_list_fixed_length = 0; } else { - set_adaptive_young_list_length(false); _young_list_fixed_length = initial_region_num; } _free_regions_at_end_of_collection = _g1->free_regions(); update_young_list_target_length(); // We may immediately start allocating regions and placing them on the // collection set list. Initialize the per-collection set info start_incremental_cset_building(); } --- 466,521 ---- size_t max_young_region_num() { return size_to_region_num(_max_gen0_size); } }; + void G1CollectorPolicy::update_young_list_size_using_newratio(size_t number_of_heap_regions) { + assert(number_of_heap_regions > 0, "Heap must be initialized"); + size_t young_size = number_of_heap_regions / (NewRatio + 1); + _min_desired_young_length = young_size; + _max_desired_young_length = young_size; + } + void G1CollectorPolicy::init() { // Set aside an initial future to_space. _g1 = G1CollectedHeap::heap(); assert(Heap_lock->owned_by_self(), "Locking discipline."); initialize_gc_policy_counters(); G1YoungGenSizer sizer; size_t initial_region_num = sizer.initial_young_region_num(); + _min_desired_young_length = sizer.min_young_region_num(); + _max_desired_young_length = sizer.max_young_region_num(); + + if (FLAG_IS_CMDLINE(NewRatio)) { + if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) { + gclog_or_tty->print_cr("-XX:NewSize and -XX:MaxNewSize overrides -XX:NewRatio"); + } else { + // Treat NewRatio as a fixed size that is only recalculated when the heap size changes + size_t heap_regions = sizer.size_to_region_num(_g1->n_regions()); + update_young_list_size_using_newratio(heap_regions); + _using_new_ratio_calculations = true; + } + } ! // GenCollectorPolicy guarantees that min <= initial <= max. ! // Asserting here just to state that we rely on this property. ! assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values"); ! assert(initial_region_num <= _max_desired_young_length, "Initial young gen size too large"); ! assert(_min_desired_young_length <= initial_region_num, "Initial young gen size too small"); ! ! set_adaptive_young_list_length(_min_desired_young_length < _max_desired_young_length); ! if (adaptive_young_list_length()) { _young_list_fixed_length = 0; } else { _young_list_fixed_length = initial_region_num; } _free_regions_at_end_of_collection = _g1->free_regions(); update_young_list_target_length(); + _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes; // We may immediately start allocating regions and placing them on the // collection set list. Initialize the per-collection set info start_incremental_cset_building(); }
*** 527,541 **** // success! return true; } ! void G1CollectorPolicy::calculate_reserve(size_t all_regions) { ! double reserve_regions_d = (double) all_regions * _reserve_factor; // We use ceiling so that if reserve_regions_d is > 0.0 (but // smaller than 1.0) we'll get 1. _reserve_regions = (size_t) ceil(reserve_regions_d); } size_t G1CollectorPolicy::calculate_young_list_desired_min_length( size_t base_min_length) { size_t desired_min_length = 0; --- 554,575 ---- // success! return true; } ! void G1CollectorPolicy::record_new_heap_size(size_t new_number_of_regions) { ! // re-calculate the necessary reserve ! double reserve_regions_d = (double) new_number_of_regions * _reserve_factor; // We use ceiling so that if reserve_regions_d is > 0.0 (but // smaller than 1.0) we'll get 1. _reserve_regions = (size_t) ceil(reserve_regions_d); + + if (_using_new_ratio_calculations) { + // -XX:NewRatio was specified so we need to update the + // young gen length when the heap size has changed. + update_young_list_size_using_newratio(new_number_of_regions); + } } size_t G1CollectorPolicy::calculate_young_list_desired_min_length( size_t base_min_length) { size_t desired_min_length = 0;
*** 547,566 **** desired_min_length = (size_t) ceil(alloc_rate_ms * when_ms); } else { // otherwise we don't have enough info to make the prediction } } ! // Here, we might want to also take into account any additional ! // constraints (i.e., user-defined minimum bound). Currently, we don't. ! return base_min_length + desired_min_length; } size_t G1CollectorPolicy::calculate_young_list_desired_max_length() { // Here, we might want to also take into account any additional // constraints (i.e., user-defined minimum bound). Currently, we // effectively don't set this bound. ! return _g1->n_regions(); } void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) { if (rs_lengths == (size_t) -1) { // if it's set to the default value (-1), we should predict it; --- 581,600 ---- desired_min_length = (size_t) ceil(alloc_rate_ms * when_ms); } else { // otherwise we don't have enough info to make the prediction } } ! desired_min_length += base_min_length; ! // make sure we don't go below any user-defined minimum bound ! return MAX2(_min_desired_young_length, desired_min_length); } size_t G1CollectorPolicy::calculate_young_list_desired_max_length() { // Here, we might want to also take into account any additional // constraints (i.e., user-defined minimum bound). Currently, we // effectively don't set this bound. ! return _max_desired_young_length; } void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) { if (rs_lengths == (size_t) -1) { // if it's set to the default value (-1), we should predict it;
*** 1649,1672 **** size_t eden_bytes = young_list->eden_used_bytes(); size_t survivor_bytes = young_list->survivor_used_bytes(); size_t used_before_gc = _cur_collection_pause_used_at_start_bytes; size_t used = _g1->used(); size_t capacity = _g1->capacity(); gclog_or_tty->print_cr( ! " [Eden: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" " "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" " "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->" EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]", EXT_SIZE_PARAMS(_eden_bytes_before_gc), EXT_SIZE_PARAMS(eden_bytes), EXT_SIZE_PARAMS(_survivor_bytes_before_gc), EXT_SIZE_PARAMS(survivor_bytes), EXT_SIZE_PARAMS(used_before_gc), EXT_SIZE_PARAMS(_capacity_before_gc), EXT_SIZE_PARAMS(used), EXT_SIZE_PARAMS(capacity)); } else if (PrintGC) { _g1->print_size_transition(gclog_or_tty, _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity()); } --- 1683,1712 ---- size_t eden_bytes = young_list->eden_used_bytes(); size_t survivor_bytes = young_list->survivor_used_bytes(); size_t used_before_gc = _cur_collection_pause_used_at_start_bytes; size_t used = _g1->used(); size_t capacity = _g1->capacity(); + size_t eden_capacity = + (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes; gclog_or_tty->print_cr( ! " [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") " "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" " "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->" EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]", EXT_SIZE_PARAMS(_eden_bytes_before_gc), + EXT_SIZE_PARAMS(_prev_eden_capacity), EXT_SIZE_PARAMS(eden_bytes), + EXT_SIZE_PARAMS(eden_capacity), EXT_SIZE_PARAMS(_survivor_bytes_before_gc), EXT_SIZE_PARAMS(survivor_bytes), EXT_SIZE_PARAMS(used_before_gc), EXT_SIZE_PARAMS(_capacity_before_gc), EXT_SIZE_PARAMS(used), EXT_SIZE_PARAMS(capacity)); + + _prev_eden_capacity = eden_capacity; } else if (PrintGC) { _g1->print_size_transition(gclog_or_tty, _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity()); }