1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Sep 08 05:16:49 2011 -0400 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Sep 08 16:29:41 2011 +0200 1.3 @@ -146,6 +146,7 @@ 1.4 _stop_world_start(0.0), 1.5 _all_stop_world_times_ms(new NumberSeq()), 1.6 _all_yield_times_ms(new NumberSeq()), 1.7 + _using_new_ratio_calculations(false), 1.8 1.9 _all_mod_union_times_ms(new NumberSeq()), 1.10 1.11 @@ -430,7 +431,7 @@ 1.12 "it's been updated to %u", reserve_perc); 1.13 } 1.14 _reserve_factor = (double) reserve_perc / 100.0; 1.15 - // This will be set in calculate_reserve() when the heap is expanded 1.16 + // This will be set when the heap is expanded 1.17 // for the first time during initialization. 1.18 _reserve_regions = 0; 1.19 1.20 @@ -458,16 +459,15 @@ 1.21 // ParallelScavengeHeap::initialize()). We might change this in the 1.22 // future, but it's a good start. 1.23 class G1YoungGenSizer : public TwoGenerationCollectorPolicy { 1.24 - size_t size_to_region_num(size_t byte_size) { 1.25 - return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes); 1.26 - } 1.27 1.28 public: 1.29 G1YoungGenSizer() { 1.30 initialize_flags(); 1.31 initialize_size_info(); 1.32 } 1.33 - 1.34 + size_t size_to_region_num(size_t byte_size) { 1.35 + return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes); 1.36 + } 1.37 size_t min_young_region_num() { 1.38 return size_to_region_num(_min_gen0_size); 1.39 } 1.40 @@ -479,6 +479,13 @@ 1.41 } 1.42 }; 1.43 1.44 +void G1CollectorPolicy::update_young_list_size_using_newratio(size_t number_of_heap_regions) { 1.45 + assert(number_of_heap_regions > 0, "Heap must be initialized"); 1.46 + size_t young_size = number_of_heap_regions / (NewRatio + 1); 1.47 + _min_desired_young_length = young_size; 1.48 + _max_desired_young_length = young_size; 1.49 +} 1.50 + 1.51 void G1CollectorPolicy::init() { 1.52 // Set aside an initial future to_space. 1.53 _g1 = G1CollectedHeap::heap(); 1.54 @@ -489,16 +496,35 @@ 1.55 1.56 G1YoungGenSizer sizer; 1.57 size_t initial_region_num = sizer.initial_young_region_num(); 1.58 - 1.59 - if (UseAdaptiveSizePolicy) { 1.60 - set_adaptive_young_list_length(true); 1.61 + _min_desired_young_length = sizer.min_young_region_num(); 1.62 + _max_desired_young_length = sizer.max_young_region_num(); 1.63 + 1.64 + if (FLAG_IS_CMDLINE(NewRatio)) { 1.65 + if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) { 1.66 + gclog_or_tty->print_cr("-XX:NewSize and -XX:MaxNewSize overrides -XX:NewRatio"); 1.67 + } else { 1.68 + // Treat NewRatio as a fixed size that is only recalculated when the heap size changes 1.69 + size_t heap_regions = sizer.size_to_region_num(_g1->n_regions()); 1.70 + update_young_list_size_using_newratio(heap_regions); 1.71 + _using_new_ratio_calculations = true; 1.72 + } 1.73 + } 1.74 + 1.75 + // GenCollectorPolicy guarantees that min <= initial <= max. 1.76 + // Asserting here just to state that we rely on this property. 1.77 + assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values"); 1.78 + assert(initial_region_num <= _max_desired_young_length, "Initial young gen size too large"); 1.79 + assert(_min_desired_young_length <= initial_region_num, "Initial young gen size too small"); 1.80 + 1.81 + set_adaptive_young_list_length(_min_desired_young_length < _max_desired_young_length); 1.82 + if (adaptive_young_list_length()) { 1.83 _young_list_fixed_length = 0; 1.84 } else { 1.85 - set_adaptive_young_list_length(false); 1.86 _young_list_fixed_length = initial_region_num; 1.87 } 1.88 _free_regions_at_end_of_collection = _g1->free_regions(); 1.89 update_young_list_target_length(); 1.90 + _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes; 1.91 1.92 // We may immediately start allocating regions and placing them on the 1.93 // collection set list. Initialize the per-collection set info 1.94 @@ -541,11 +567,18 @@ 1.95 return true; 1.96 } 1.97 1.98 -void G1CollectorPolicy::calculate_reserve(size_t all_regions) { 1.99 - double reserve_regions_d = (double) all_regions * _reserve_factor; 1.100 +void G1CollectorPolicy::record_new_heap_size(size_t new_number_of_regions) { 1.101 + // re-calculate the necessary reserve 1.102 + double reserve_regions_d = (double) new_number_of_regions * _reserve_factor; 1.103 // We use ceiling so that if reserve_regions_d is > 0.0 (but 1.104 // smaller than 1.0) we'll get 1. 1.105 _reserve_regions = (size_t) ceil(reserve_regions_d); 1.106 + 1.107 + if (_using_new_ratio_calculations) { 1.108 + // -XX:NewRatio was specified so we need to update the 1.109 + // young gen length when the heap size has changed. 1.110 + update_young_list_size_using_newratio(new_number_of_regions); 1.111 + } 1.112 } 1.113 1.114 size_t G1CollectorPolicy::calculate_young_list_desired_min_length( 1.115 @@ -561,16 +594,16 @@ 1.116 // otherwise we don't have enough info to make the prediction 1.117 } 1.118 } 1.119 - // Here, we might want to also take into account any additional 1.120 - // constraints (i.e., user-defined minimum bound). Currently, we don't. 1.121 - return base_min_length + desired_min_length; 1.122 + desired_min_length += base_min_length; 1.123 + // make sure we don't go below any user-defined minimum bound 1.124 + return MAX2(_min_desired_young_length, desired_min_length); 1.125 } 1.126 1.127 size_t G1CollectorPolicy::calculate_young_list_desired_max_length() { 1.128 // Here, we might want to also take into account any additional 1.129 // constraints (i.e., user-defined minimum bound). Currently, we 1.130 // effectively don't set this bound. 1.131 - return _g1->n_regions(); 1.132 + return _max_desired_young_length; 1.133 } 1.134 1.135 void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) { 1.136 @@ -1699,20 +1732,26 @@ 1.137 size_t used_before_gc = _cur_collection_pause_used_at_start_bytes; 1.138 size_t used = _g1->used(); 1.139 size_t capacity = _g1->capacity(); 1.140 + size_t eden_capacity = 1.141 + (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes; 1.142 1.143 gclog_or_tty->print_cr( 1.144 - " [Eden: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" " 1.145 - "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" " 1.146 - "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->" 1.147 - EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]", 1.148 - EXT_SIZE_PARAMS(_eden_bytes_before_gc), 1.149 - EXT_SIZE_PARAMS(eden_bytes), 1.150 - EXT_SIZE_PARAMS(_survivor_bytes_before_gc), 1.151 - EXT_SIZE_PARAMS(survivor_bytes), 1.152 - EXT_SIZE_PARAMS(used_before_gc), 1.153 - EXT_SIZE_PARAMS(_capacity_before_gc), 1.154 - EXT_SIZE_PARAMS(used), 1.155 - EXT_SIZE_PARAMS(capacity)); 1.156 + " [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") " 1.157 + "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" " 1.158 + "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->" 1.159 + EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]", 1.160 + EXT_SIZE_PARAMS(_eden_bytes_before_gc), 1.161 + EXT_SIZE_PARAMS(_prev_eden_capacity), 1.162 + EXT_SIZE_PARAMS(eden_bytes), 1.163 + EXT_SIZE_PARAMS(eden_capacity), 1.164 + EXT_SIZE_PARAMS(_survivor_bytes_before_gc), 1.165 + EXT_SIZE_PARAMS(survivor_bytes), 1.166 + EXT_SIZE_PARAMS(used_before_gc), 1.167 + EXT_SIZE_PARAMS(_capacity_before_gc), 1.168 + EXT_SIZE_PARAMS(used), 1.169 + EXT_SIZE_PARAMS(capacity)); 1.170 + 1.171 + _prev_eden_capacity = eden_capacity; 1.172 } else if (PrintGC) { 1.173 _g1->print_size_transition(gclog_or_tty, 1.174 _cur_collection_pause_used_at_start_bytes,