1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Aug 19 14:22:25 2011 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Aug 19 09:30:59 2011 +0200 1.3 @@ -170,7 +170,6 @@ 1.4 _cur_aux_times_ms(new double[_aux_num]), 1.5 _cur_aux_times_set(new bool[_aux_num]), 1.6 1.7 - _concurrent_mark_init_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), 1.8 _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), 1.9 _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), 1.10 1.11 @@ -201,7 +200,6 @@ 1.12 1.13 // </NEW PREDICTION> 1.14 1.15 - _in_young_gc_mode(false), 1.16 _full_young_gcs(true), 1.17 _full_young_pause_num(0), 1.18 _partial_young_pause_num(0), 1.19 @@ -400,7 +398,6 @@ 1.20 _sigma = (double) G1ConfidencePercent / 100.0; 1.21 1.22 // start conservatively (around 50ms is about right) 1.23 - _concurrent_mark_init_times_ms->add(0.05); 1.24 _concurrent_mark_remark_times_ms->add(0.05); 1.25 _concurrent_mark_cleanup_times_ms->add(0.20); 1.26 _tenuring_threshold = MaxTenuringThreshold; 1.27 @@ -468,27 +465,20 @@ 1.28 1.29 initialize_gc_policy_counters(); 1.30 1.31 - if (G1Gen) { 1.32 - _in_young_gc_mode = true; 1.33 - 1.34 - G1YoungGenSizer sizer; 1.35 - size_t initial_region_num = sizer.initial_young_region_num(); 1.36 - 1.37 - if (UseAdaptiveSizePolicy) { 1.38 - set_adaptive_young_list_length(true); 1.39 - _young_list_fixed_length = 0; 1.40 - } else { 1.41 - set_adaptive_young_list_length(false); 1.42 - _young_list_fixed_length = initial_region_num; 1.43 - } 1.44 - _free_regions_at_end_of_collection = _g1->free_regions(); 1.45 - calculate_young_list_min_length(); 1.46 - guarantee( _young_list_min_length == 0, "invariant, not enough info" ); 1.47 - calculate_young_list_target_length(); 1.48 + G1YoungGenSizer sizer; 1.49 + size_t initial_region_num = sizer.initial_young_region_num(); 1.50 + 1.51 + if (UseAdaptiveSizePolicy) { 1.52 + set_adaptive_young_list_length(true); 1.53 + _young_list_fixed_length = 0; 1.54 } else { 1.55 - _young_list_fixed_length = 0; 1.56 - _in_young_gc_mode = false; 1.57 + set_adaptive_young_list_length(false); 1.58 + _young_list_fixed_length = initial_region_num; 1.59 } 1.60 + _free_regions_at_end_of_collection = _g1->free_regions(); 1.61 + calculate_young_list_min_length(); 1.62 + guarantee( _young_list_min_length == 0, "invariant, not enough info" ); 1.63 + calculate_young_list_target_length(); 1.64 1.65 // We may immediately start allocating regions and placing them on the 1.66 // collection set list. Initialize the per-collection set info 1.67 @@ -498,7 +488,7 @@ 1.68 // Create the jstat counters for the policy. 1.69 void G1CollectorPolicy::initialize_gc_policy_counters() 1.70 { 1.71 - _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 2 + G1Gen); 1.72 + _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3); 1.73 } 1.74 1.75 void G1CollectorPolicy::calculate_young_list_min_length() { 1.76 @@ -868,8 +858,7 @@ 1.77 if (PrintGCDetails) { 1.78 gclog_or_tty->stamp(PrintGCTimeStamps); 1.79 gclog_or_tty->print("[GC pause"); 1.80 - if (in_young_gc_mode()) 1.81 - gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial"); 1.82 + gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial"); 1.83 } 1.84 1.85 assert(_g1->used() == _g1->recalculate_used(), 1.86 @@ -921,8 +910,7 @@ 1.87 _satb_drain_time_set = false; 1.88 _last_satb_drain_processed_buffers = -1; 1.89 1.90 - if (in_young_gc_mode()) 1.91 - _last_young_gc_full = false; 1.92 + _last_young_gc_full = false; 1.93 1.94 // do that for any other surv rate groups 1.95 _short_lived_surv_rate_group->stop_adding_regions(); 1.96 @@ -935,12 +923,7 @@ 1.97 _mark_closure_time_ms = mark_closure_time_ms; 1.98 } 1.99 1.100 -void G1CollectorPolicy::record_concurrent_mark_init_start() { 1.101 - _mark_init_start_sec = os::elapsedTime(); 1.102 - guarantee(!in_young_gc_mode(), "should not do be here in young GC mode"); 1.103 -} 1.104 - 1.105 -void G1CollectorPolicy::record_concurrent_mark_init_end_pre(double 1.106 +void G1CollectorPolicy::record_concurrent_mark_init_end(double 1.107 mark_init_elapsed_time_ms) { 1.108 _during_marking = true; 1.109 assert(!initiate_conc_mark_if_possible(), "we should have cleared it by now"); 1.110 @@ -948,15 +931,6 @@ 1.111 _cur_mark_stop_world_time_ms = mark_init_elapsed_time_ms; 1.112 } 1.113 1.114 -void G1CollectorPolicy::record_concurrent_mark_init_end() { 1.115 - double end_time_sec = os::elapsedTime(); 1.116 - double elapsed_time_ms = (end_time_sec - _mark_init_start_sec) * 1000.0; 1.117 - _concurrent_mark_init_times_ms->add(elapsed_time_ms); 1.118 - record_concurrent_mark_init_end_pre(elapsed_time_ms); 1.119 - 1.120 - _mmu_tracker->add_pause(_mark_init_start_sec, end_time_sec, true); 1.121 -} 1.122 - 1.123 void G1CollectorPolicy::record_concurrent_mark_remark_start() { 1.124 _mark_remark_start_sec = os::elapsedTime(); 1.125 _during_marking = false; 1.126 @@ -1019,13 +993,11 @@ 1.127 1.128 void 1.129 G1CollectorPolicy::record_concurrent_mark_cleanup_completed() { 1.130 - if (in_young_gc_mode()) { 1.131 - _should_revert_to_full_young_gcs = false; 1.132 - _last_full_young_gc = true; 1.133 - _in_marking_window = false; 1.134 - if (adaptive_young_list_length()) 1.135 - calculate_young_list_target_length(); 1.136 - } 1.137 + _should_revert_to_full_young_gcs = false; 1.138 + _last_full_young_gc = true; 1.139 + _in_marking_window = false; 1.140 + if (adaptive_young_list_length()) 1.141 + calculate_young_list_target_length(); 1.142 } 1.143 1.144 void G1CollectorPolicy::record_concurrent_pause() { 1.145 @@ -1174,31 +1146,29 @@ 1.146 } 1.147 #endif // PRODUCT 1.148 1.149 - if (in_young_gc_mode()) { 1.150 - last_pause_included_initial_mark = during_initial_mark_pause(); 1.151 - if (last_pause_included_initial_mark) 1.152 - record_concurrent_mark_init_end_pre(0.0); 1.153 - 1.154 - size_t min_used_targ = 1.155 - (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent; 1.156 - 1.157 - 1.158 - if (!_g1->mark_in_progress() && !_last_full_young_gc) { 1.159 - assert(!last_pause_included_initial_mark, "invariant"); 1.160 - if (cur_used_bytes > min_used_targ && 1.161 - cur_used_bytes > _prev_collection_pause_used_at_end_bytes) { 1.162 + last_pause_included_initial_mark = during_initial_mark_pause(); 1.163 + if (last_pause_included_initial_mark) 1.164 + record_concurrent_mark_init_end(0.0); 1.165 + 1.166 + size_t min_used_targ = 1.167 + (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent; 1.168 + 1.169 + 1.170 + if (!_g1->mark_in_progress() && !_last_full_young_gc) { 1.171 + assert(!last_pause_included_initial_mark, "invariant"); 1.172 + if (cur_used_bytes > min_used_targ && 1.173 + cur_used_bytes > _prev_collection_pause_used_at_end_bytes) { 1.174 assert(!during_initial_mark_pause(), "we should not see this here"); 1.175 1.176 // Note: this might have already been set, if during the last 1.177 // pause we decided to start a cycle but at the beginning of 1.178 // this pause we decided to postpone it. That's OK. 1.179 set_initiate_conc_mark_if_possible(); 1.180 - } 1.181 } 1.182 - 1.183 - _prev_collection_pause_used_at_end_bytes = cur_used_bytes; 1.184 } 1.185 1.186 + _prev_collection_pause_used_at_end_bytes = cur_used_bytes; 1.187 + 1.188 _mmu_tracker->add_pause(end_time_sec - elapsed_ms/1000.0, 1.189 end_time_sec, false); 1.190 1.191 @@ -1468,24 +1438,23 @@ 1.192 new_in_marking_window_im = true; 1.193 } 1.194 1.195 - if (in_young_gc_mode()) { 1.196 - if (_last_full_young_gc) { 1.197 - set_full_young_gcs(false); 1.198 - _last_full_young_gc = false; 1.199 + if (_last_full_young_gc) { 1.200 + set_full_young_gcs(false); 1.201 + _last_full_young_gc = false; 1.202 + } 1.203 + 1.204 + if ( !_last_young_gc_full ) { 1.205 + if ( _should_revert_to_full_young_gcs || 1.206 + _known_garbage_ratio < 0.05 || 1.207 + (adaptive_young_list_length() && 1.208 + (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) ) { 1.209 + set_full_young_gcs(true); 1.210 } 1.211 - 1.212 - if ( !_last_young_gc_full ) { 1.213 - if ( _should_revert_to_full_young_gcs || 1.214 - _known_garbage_ratio < 0.05 || 1.215 - (adaptive_young_list_length() && 1.216 - (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) ) { 1.217 - set_full_young_gcs(true); 1.218 - } 1.219 - } 1.220 - _should_revert_to_full_young_gcs = false; 1.221 - 1.222 - if (_last_young_gc_full && !_during_marking) 1.223 - _young_gc_eff_seq->add(cur_efficiency); 1.224 + } 1.225 + _should_revert_to_full_young_gcs = false; 1.226 + 1.227 + if (_last_young_gc_full && !_during_marking) { 1.228 + _young_gc_eff_seq->add(cur_efficiency); 1.229 } 1.230 1.231 _short_lived_surv_rate_group->start_adding_regions(); 1.232 @@ -1910,18 +1879,8 @@ 1.233 // I don't think we need to do this when in young GC mode since 1.234 // marking will be initiated next time we hit the soft limit anyway... 1.235 if (predicted_time_ms > _expensive_region_limit_ms) { 1.236 - if (!in_young_gc_mode()) { 1.237 - set_full_young_gcs(true); 1.238 - // We might want to do something different here. However, 1.239 - // right now we don't support the non-generational G1 mode 1.240 - // (and in fact we are planning to remove the associated code, 1.241 - // see CR 6814390). So, let's leave it as is and this will be 1.242 - // removed some time in the future 1.243 - ShouldNotReachHere(); 1.244 - set_during_initial_mark_pause(); 1.245 - } else 1.246 - // no point in doing another partial one 1.247 - _should_revert_to_full_young_gcs = true; 1.248 + // no point in doing another partial one 1.249 + _should_revert_to_full_young_gcs = true; 1.250 } 1.251 } 1.252 1.253 @@ -2617,9 +2576,7 @@ 1.254 _inc_cset_size = 0; 1.255 _inc_cset_bytes_used_before = 0; 1.256 1.257 - if (in_young_gc_mode()) { 1.258 - _inc_cset_young_index = 0; 1.259 - } 1.260 + _inc_cset_young_index = 0; 1.261 1.262 _inc_cset_max_finger = 0; 1.263 _inc_cset_recorded_young_bytes = 0; 1.264 @@ -2848,86 +2805,77 @@ 1.265 max_live_bytes = max_live_bytes + expansion_bytes; 1.266 1.267 HeapRegion* hr; 1.268 - if (in_young_gc_mode()) { 1.269 - double young_start_time_sec = os::elapsedTime(); 1.270 - 1.271 - if (G1PolicyVerbose > 0) { 1.272 - gclog_or_tty->print_cr("Adding %d young regions to the CSet", 1.273 - _g1->young_list()->length()); 1.274 - } 1.275 - 1.276 - _young_cset_length = 0; 1.277 - _last_young_gc_full = full_young_gcs() ? true : false; 1.278 - 1.279 - if (_last_young_gc_full) 1.280 - ++_full_young_pause_num; 1.281 - else 1.282 - ++_partial_young_pause_num; 1.283 - 1.284 - // The young list is laid with the survivor regions from the previous 1.285 - // pause are appended to the RHS of the young list, i.e. 1.286 - // [Newly Young Regions ++ Survivors from last pause]. 1.287 - 1.288 - hr = _g1->young_list()->first_survivor_region(); 1.289 - while (hr != NULL) { 1.290 - assert(hr->is_survivor(), "badly formed young list"); 1.291 - hr->set_young(); 1.292 - hr = hr->get_next_young_region(); 1.293 - } 1.294 - 1.295 - // Clear the fields that point to the survivor list - they are 1.296 - // all young now. 1.297 - _g1->young_list()->clear_survivors(); 1.298 - 1.299 - if (_g1->mark_in_progress()) 1.300 - _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger); 1.301 - 1.302 - _young_cset_length = _inc_cset_young_index; 1.303 - _collection_set = _inc_cset_head; 1.304 - _collection_set_size = _inc_cset_size; 1.305 - _collection_set_bytes_used_before = _inc_cset_bytes_used_before; 1.306 - 1.307 - // For young regions in the collection set, we assume the worst 1.308 - // case of complete survival 1.309 - max_live_bytes -= _inc_cset_size * HeapRegion::GrainBytes; 1.310 - 1.311 - time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms; 1.312 - predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; 1.313 - 1.314 - // The number of recorded young regions is the incremental 1.315 - // collection set's current size 1.316 - set_recorded_young_regions(_inc_cset_size); 1.317 - set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths); 1.318 - set_recorded_young_bytes(_inc_cset_recorded_young_bytes); 1.319 + double young_start_time_sec = os::elapsedTime(); 1.320 + 1.321 + if (G1PolicyVerbose > 0) { 1.322 + gclog_or_tty->print_cr("Adding %d young regions to the CSet", 1.323 + _g1->young_list()->length()); 1.324 + } 1.325 + 1.326 + _young_cset_length = 0; 1.327 + _last_young_gc_full = full_young_gcs() ? true : false; 1.328 + 1.329 + if (_last_young_gc_full) 1.330 + ++_full_young_pause_num; 1.331 + else 1.332 + ++_partial_young_pause_num; 1.333 + 1.334 + // The young list is laid with the survivor regions from the previous 1.335 + // pause are appended to the RHS of the young list, i.e. 1.336 + // [Newly Young Regions ++ Survivors from last pause]. 1.337 + 1.338 + hr = _g1->young_list()->first_survivor_region(); 1.339 + while (hr != NULL) { 1.340 + assert(hr->is_survivor(), "badly formed young list"); 1.341 + hr->set_young(); 1.342 + hr = hr->get_next_young_region(); 1.343 + } 1.344 + 1.345 + // Clear the fields that point to the survivor list - they are 1.346 + // all young now. 1.347 + _g1->young_list()->clear_survivors(); 1.348 + 1.349 + if (_g1->mark_in_progress()) 1.350 + _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger); 1.351 + 1.352 + _young_cset_length = _inc_cset_young_index; 1.353 + _collection_set = _inc_cset_head; 1.354 + _collection_set_size = _inc_cset_size; 1.355 + _collection_set_bytes_used_before = _inc_cset_bytes_used_before; 1.356 + 1.357 + // For young regions in the collection set, we assume the worst 1.358 + // case of complete survival 1.359 + max_live_bytes -= _inc_cset_size * HeapRegion::GrainBytes; 1.360 + 1.361 + time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms; 1.362 + predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; 1.363 + 1.364 + // The number of recorded young regions is the incremental 1.365 + // collection set's current size 1.366 + set_recorded_young_regions(_inc_cset_size); 1.367 + set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths); 1.368 + set_recorded_young_bytes(_inc_cset_recorded_young_bytes); 1.369 #if PREDICTIONS_VERBOSE 1.370 - set_predicted_bytes_to_copy(_inc_cset_predicted_bytes_to_copy); 1.371 + set_predicted_bytes_to_copy(_inc_cset_predicted_bytes_to_copy); 1.372 #endif // PREDICTIONS_VERBOSE 1.373 1.374 - if (G1PolicyVerbose > 0) { 1.375 - gclog_or_tty->print_cr(" Added " PTR_FORMAT " Young Regions to CS.", 1.376 - _inc_cset_size); 1.377 - gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)", 1.378 - max_live_bytes/K); 1.379 - } 1.380 - 1.381 - assert(_inc_cset_size == _g1->young_list()->length(), "Invariant"); 1.382 - 1.383 - double young_end_time_sec = os::elapsedTime(); 1.384 - _recorded_young_cset_choice_time_ms = 1.385 - (young_end_time_sec - young_start_time_sec) * 1000.0; 1.386 - 1.387 - // We are doing young collections so reset this. 1.388 - non_young_start_time_sec = young_end_time_sec; 1.389 - 1.390 - // Note we can use either _collection_set_size or 1.391 - // _young_cset_length here 1.392 - if (_collection_set_size > 0 && _last_young_gc_full) { 1.393 - // don't bother adding more regions... 1.394 - goto choose_collection_set_end; 1.395 - } 1.396 + if (G1PolicyVerbose > 0) { 1.397 + gclog_or_tty->print_cr(" Added " PTR_FORMAT " Young Regions to CS.", 1.398 + _inc_cset_size); 1.399 + gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)", 1.400 + max_live_bytes/K); 1.401 } 1.402 1.403 - if (!in_young_gc_mode() || !full_young_gcs()) { 1.404 + assert(_inc_cset_size == _g1->young_list()->length(), "Invariant"); 1.405 + 1.406 + double young_end_time_sec = os::elapsedTime(); 1.407 + _recorded_young_cset_choice_time_ms = 1.408 + (young_end_time_sec - young_start_time_sec) * 1000.0; 1.409 + 1.410 + // We are doing young collections so reset this. 1.411 + non_young_start_time_sec = young_end_time_sec; 1.412 + 1.413 + if (!full_young_gcs()) { 1.414 bool should_continue = true; 1.415 NumberSeq seq; 1.416 double avg_prediction = 100000000000000000.0; // something very large 1.417 @@ -2960,7 +2908,6 @@ 1.418 _should_revert_to_full_young_gcs = true; 1.419 } 1.420 1.421 -choose_collection_set_end: 1.422 stop_incremental_cset_building(); 1.423 1.424 count_CS_bytes_used();