Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 4090:a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
Summary: Major cleanup of the G1CollectorPolicy class. It removes a lot of unused fields and methods and also consolidates replicated information (mainly various ways of counting the number of CSet regions) into one copy.
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 18 Nov 2011 12:52:27 -0500 |
parents | 8aae2050e83e |
children | bca17e38de00 |
comparison
equal
deleted
inserted
replaced
4077:b1754f3fbbd8 | 4090:a88de71c4e3a |
---|---|
34 #include "runtime/arguments.hpp" | 34 #include "runtime/arguments.hpp" |
35 #include "runtime/java.hpp" | 35 #include "runtime/java.hpp" |
36 #include "runtime/mutexLocker.hpp" | 36 #include "runtime/mutexLocker.hpp" |
37 #include "utilities/debug.hpp" | 37 #include "utilities/debug.hpp" |
38 | 38 |
39 #define PREDICTIONS_VERBOSE 0 | |
40 | |
41 // <NEW PREDICTION> | |
42 | |
43 // Different defaults for different number of GC threads | 39 // Different defaults for different number of GC threads |
44 // They were chosen by running GCOld and SPECjbb on debris with different | 40 // They were chosen by running GCOld and SPECjbb on debris with different |
45 // numbers of GC threads and choosing them based on the results | 41 // numbers of GC threads and choosing them based on the results |
46 | 42 |
47 // all the same | 43 // all the same |
77 }; | 73 }; |
78 | 74 |
79 static double non_young_other_cost_per_region_ms_defaults[] = { | 75 static double non_young_other_cost_per_region_ms_defaults[] = { |
80 1.0, 0.7, 0.7, 0.5, 0.5, 0.42, 0.42, 0.30 | 76 1.0, 0.7, 0.7, 0.5, 0.5, 0.42, 0.42, 0.30 |
81 }; | 77 }; |
82 | |
83 // </NEW PREDICTION> | |
84 | 78 |
85 // Help class for avoiding interleaved logging | 79 // Help class for avoiding interleaved logging |
86 class LineBuffer: public StackObj { | 80 class LineBuffer: public StackObj { |
87 | 81 |
88 private: | 82 private: |
135 | 129 |
136 G1CollectorPolicy::G1CollectorPolicy() : | 130 G1CollectorPolicy::G1CollectorPolicy() : |
137 _parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads() | 131 _parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads() |
138 ? ParallelGCThreads : 1), | 132 ? ParallelGCThreads : 1), |
139 | 133 |
140 _n_pauses(0), | |
141 _recent_rs_scan_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), | |
142 _recent_pause_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), | |
143 _recent_rs_sizes(new TruncatedSeq(NumPrevPausesForHeuristics)), | |
144 _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), | 134 _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), |
145 _all_pause_times_ms(new NumberSeq()), | 135 _all_pause_times_ms(new NumberSeq()), |
146 _stop_world_start(0.0), | 136 _stop_world_start(0.0), |
147 _all_stop_world_times_ms(new NumberSeq()), | 137 _all_stop_world_times_ms(new NumberSeq()), |
148 _all_yield_times_ms(new NumberSeq()), | 138 _all_yield_times_ms(new NumberSeq()), |
149 _using_new_ratio_calculations(false), | 139 _using_new_ratio_calculations(false), |
150 | |
151 _all_mod_union_times_ms(new NumberSeq()), | |
152 | 140 |
153 _summary(new Summary()), | 141 _summary(new Summary()), |
154 | 142 |
155 _cur_clear_ct_time_ms(0.0), | 143 _cur_clear_ct_time_ms(0.0), |
156 | 144 |
163 _cur_clear_cc_time_ms(0.0), | 151 _cur_clear_cc_time_ms(0.0), |
164 _cum_clear_cc_time_ms(0.0), | 152 _cum_clear_cc_time_ms(0.0), |
165 _num_cc_clears(0L), | 153 _num_cc_clears(0L), |
166 #endif | 154 #endif |
167 | 155 |
168 _region_num_young(0), | |
169 _region_num_tenured(0), | |
170 _prev_region_num_young(0), | |
171 _prev_region_num_tenured(0), | |
172 | |
173 _aux_num(10), | 156 _aux_num(10), |
174 _all_aux_times_ms(new NumberSeq[_aux_num]), | 157 _all_aux_times_ms(new NumberSeq[_aux_num]), |
175 _cur_aux_start_times_ms(new double[_aux_num]), | 158 _cur_aux_start_times_ms(new double[_aux_num]), |
176 _cur_aux_times_ms(new double[_aux_num]), | 159 _cur_aux_times_ms(new double[_aux_num]), |
177 _cur_aux_times_set(new bool[_aux_num]), | 160 _cur_aux_times_set(new bool[_aux_num]), |
178 | 161 |
179 _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), | 162 _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), |
180 _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), | 163 _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), |
181 | |
182 // <NEW PREDICTION> | |
183 | 164 |
184 _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 165 _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
185 _prev_collection_pause_end_ms(0.0), | 166 _prev_collection_pause_end_ms(0.0), |
186 _pending_card_diff_seq(new TruncatedSeq(TruncatedSeqLength)), | 167 _pending_card_diff_seq(new TruncatedSeq(TruncatedSeqLength)), |
187 _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)), | 168 _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)), |
197 _young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 178 _young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
198 _non_young_other_cost_per_region_ms_seq( | 179 _non_young_other_cost_per_region_ms_seq( |
199 new TruncatedSeq(TruncatedSeqLength)), | 180 new TruncatedSeq(TruncatedSeqLength)), |
200 | 181 |
201 _pending_cards_seq(new TruncatedSeq(TruncatedSeqLength)), | 182 _pending_cards_seq(new TruncatedSeq(TruncatedSeqLength)), |
202 _scanned_cards_seq(new TruncatedSeq(TruncatedSeqLength)), | |
203 _rs_lengths_seq(new TruncatedSeq(TruncatedSeqLength)), | 183 _rs_lengths_seq(new TruncatedSeq(TruncatedSeqLength)), |
204 | 184 |
205 _pause_time_target_ms((double) MaxGCPauseMillis), | 185 _pause_time_target_ms((double) MaxGCPauseMillis), |
206 | |
207 // </NEW PREDICTION> | |
208 | 186 |
209 _full_young_gcs(true), | 187 _full_young_gcs(true), |
210 _full_young_pause_num(0), | 188 _full_young_pause_num(0), |
211 _partial_young_pause_num(0), | 189 _partial_young_pause_num(0), |
212 | 190 |
219 | 197 |
220 _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)), | 198 _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)), |
221 | 199 |
222 _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)), | 200 _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)), |
223 | 201 |
224 _recent_CS_bytes_used_before(new TruncatedSeq(NumPrevPausesForHeuristics)), | |
225 _recent_CS_bytes_surviving(new TruncatedSeq(NumPrevPausesForHeuristics)), | |
226 | |
227 _recent_avg_pause_time_ratio(0.0), | 202 _recent_avg_pause_time_ratio(0.0), |
228 | 203 |
229 _all_full_gc_times_ms(new NumberSeq()), | 204 _all_full_gc_times_ms(new NumberSeq()), |
230 | 205 |
231 // G1PausesBtwnConcMark defaults to -1 | |
232 // so the hack is to do the cast QQQ FIXME | |
233 _pauses_btwn_concurrent_mark((size_t)G1PausesBtwnConcMark), | |
234 _initiate_conc_mark_if_possible(false), | 206 _initiate_conc_mark_if_possible(false), |
235 _during_initial_mark_pause(false), | 207 _during_initial_mark_pause(false), |
236 _should_revert_to_full_young_gcs(false), | 208 _should_revert_to_full_young_gcs(false), |
237 _last_full_young_gc(false), | 209 _last_full_young_gc(false), |
238 | 210 |
240 _survivor_bytes_before_gc(0), | 212 _survivor_bytes_before_gc(0), |
241 _capacity_before_gc(0), | 213 _capacity_before_gc(0), |
242 | 214 |
243 _prev_collection_pause_used_at_end_bytes(0), | 215 _prev_collection_pause_used_at_end_bytes(0), |
244 | 216 |
217 _eden_cset_region_length(0), | |
218 _survivor_cset_region_length(0), | |
219 _old_cset_region_length(0), | |
220 | |
245 _collection_set(NULL), | 221 _collection_set(NULL), |
246 _collection_set_size(0), | |
247 _collection_set_bytes_used_before(0), | 222 _collection_set_bytes_used_before(0), |
248 | 223 |
249 // Incremental CSet attributes | 224 // Incremental CSet attributes |
250 _inc_cset_build_state(Inactive), | 225 _inc_cset_build_state(Inactive), |
251 _inc_cset_head(NULL), | 226 _inc_cset_head(NULL), |
252 _inc_cset_tail(NULL), | 227 _inc_cset_tail(NULL), |
253 _inc_cset_size(0), | |
254 _inc_cset_young_index(0), | |
255 _inc_cset_bytes_used_before(0), | 228 _inc_cset_bytes_used_before(0), |
256 _inc_cset_max_finger(NULL), | 229 _inc_cset_max_finger(NULL), |
257 _inc_cset_recorded_young_bytes(0), | |
258 _inc_cset_recorded_rs_lengths(0), | 230 _inc_cset_recorded_rs_lengths(0), |
259 _inc_cset_predicted_elapsed_time_ms(0.0), | 231 _inc_cset_predicted_elapsed_time_ms(0.0), |
260 _inc_cset_predicted_bytes_to_copy(0), | |
261 | 232 |
262 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | 233 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away |
263 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | 234 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
264 #endif // _MSC_VER | 235 #endif // _MSC_VER |
265 | 236 |
322 _par_last_gc_worker_times_ms = new double[_parallel_gc_threads]; | 293 _par_last_gc_worker_times_ms = new double[_parallel_gc_threads]; |
323 _par_last_gc_worker_other_times_ms = new double[_parallel_gc_threads]; | 294 _par_last_gc_worker_other_times_ms = new double[_parallel_gc_threads]; |
324 | 295 |
325 // start conservatively | 296 // start conservatively |
326 _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis; | 297 _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis; |
327 | |
328 // <NEW PREDICTION> | |
329 | 298 |
330 int index; | 299 int index; |
331 if (ParallelGCThreads == 0) | 300 if (ParallelGCThreads == 0) |
332 index = 0; | 301 index = 0; |
333 else if (ParallelGCThreads > 8) | 302 else if (ParallelGCThreads > 8) |
345 _constant_other_time_ms_seq->add(constant_other_time_ms_defaults[index]); | 314 _constant_other_time_ms_seq->add(constant_other_time_ms_defaults[index]); |
346 _young_other_cost_per_region_ms_seq->add( | 315 _young_other_cost_per_region_ms_seq->add( |
347 young_other_cost_per_region_ms_defaults[index]); | 316 young_other_cost_per_region_ms_defaults[index]); |
348 _non_young_other_cost_per_region_ms_seq->add( | 317 _non_young_other_cost_per_region_ms_seq->add( |
349 non_young_other_cost_per_region_ms_defaults[index]); | 318 non_young_other_cost_per_region_ms_defaults[index]); |
350 | |
351 // </NEW PREDICTION> | |
352 | 319 |
353 // Below, we might need to calculate the pause time target based on | 320 // Below, we might need to calculate the pause time target based on |
354 // the pause interval. When we do so we are going to give G1 maximum | 321 // the pause interval. When we do so we are going to give G1 maximum |
355 // flexibility and allow it to do pauses when it needs to. So, we'll | 322 // flexibility and allow it to do pauses when it needs to. So, we'll |
356 // arrange that the pause interval to be pause time target + 1 to | 323 // arrange that the pause interval to be pause time target + 1 to |
906 _short_lived_surv_rate_group->start_adding_regions(); | 873 _short_lived_surv_rate_group->start_adding_regions(); |
907 // also call this on any additional surv rate groups | 874 // also call this on any additional surv rate groups |
908 | 875 |
909 record_survivor_regions(0, NULL, NULL); | 876 record_survivor_regions(0, NULL, NULL); |
910 | 877 |
911 _prev_region_num_young = _region_num_young; | |
912 _prev_region_num_tenured = _region_num_tenured; | |
913 | |
914 _free_regions_at_end_of_collection = _g1->free_regions(); | 878 _free_regions_at_end_of_collection = _g1->free_regions(); |
915 // Reset survivors SurvRateGroup. | 879 // Reset survivors SurvRateGroup. |
916 _survivor_surv_rate_group->reset(); | 880 _survivor_surv_rate_group->reset(); |
917 update_young_list_target_length(); | 881 update_young_list_target_length(); |
918 _collectionSetChooser->updateAfterFullCollection(); | 882 _collectionSetChooser->updateAfterFullCollection(); |
1166 | 1130 |
1167 void G1CollectorPolicy::record_collection_pause_end() { | 1131 void G1CollectorPolicy::record_collection_pause_end() { |
1168 double end_time_sec = os::elapsedTime(); | 1132 double end_time_sec = os::elapsedTime(); |
1169 double elapsed_ms = _last_pause_time_ms; | 1133 double elapsed_ms = _last_pause_time_ms; |
1170 bool parallel = G1CollectedHeap::use_parallel_gc_threads(); | 1134 bool parallel = G1CollectedHeap::use_parallel_gc_threads(); |
1135 assert(_cur_collection_pause_used_regions_at_start >= cset_region_length(), | |
1136 "otherwise, the subtraction below does not make sense"); | |
1171 size_t rs_size = | 1137 size_t rs_size = |
1172 _cur_collection_pause_used_regions_at_start - collection_set_size(); | 1138 _cur_collection_pause_used_regions_at_start - cset_region_length(); |
1173 size_t cur_used_bytes = _g1->used(); | 1139 size_t cur_used_bytes = _g1->used(); |
1174 assert(cur_used_bytes == _g1->recalculate_used(), "It should!"); | 1140 assert(cur_used_bytes == _g1->recalculate_used(), "It should!"); |
1175 bool last_pause_included_initial_mark = false; | 1141 bool last_pause_included_initial_mark = false; |
1176 bool update_stats = !_g1->evacuation_failed(); | 1142 bool update_stats = !_g1->evacuation_failed(); |
1177 | 1143 |
1223 | 1189 |
1224 _prev_collection_pause_used_at_end_bytes = cur_used_bytes; | 1190 _prev_collection_pause_used_at_end_bytes = cur_used_bytes; |
1225 | 1191 |
1226 _mmu_tracker->add_pause(end_time_sec - elapsed_ms/1000.0, | 1192 _mmu_tracker->add_pause(end_time_sec - elapsed_ms/1000.0, |
1227 end_time_sec, false); | 1193 end_time_sec, false); |
1228 | |
1229 guarantee(_cur_collection_pause_used_regions_at_start >= | |
1230 collection_set_size(), | |
1231 "Negative RS size?"); | |
1232 | 1194 |
1233 // This assert is exempted when we're doing parallel collection pauses, | 1195 // This assert is exempted when we're doing parallel collection pauses, |
1234 // because the fragmentation caused by the parallel GC allocation buffers | 1196 // because the fragmentation caused by the parallel GC allocation buffers |
1235 // can lead to more memory being used during collection than was used | 1197 // can lead to more memory being used during collection than was used |
1236 // before. Best leave this out until the fragmentation problem is fixed. | 1198 // before. Best leave this out until the fragmentation problem is fixed. |
1251 | 1213 |
1252 double survival_fraction = | 1214 double survival_fraction = |
1253 (double)surviving_bytes/ | 1215 (double)surviving_bytes/ |
1254 (double)_collection_set_bytes_used_before; | 1216 (double)_collection_set_bytes_used_before; |
1255 | 1217 |
1256 _n_pauses++; | |
1257 | |
1258 // These values are used to update the summary information that is | 1218 // These values are used to update the summary information that is |
1259 // displayed when TraceGen0Time is enabled, and are output as part | 1219 // displayed when TraceGen0Time is enabled, and are output as part |
1260 // of the PrintGCDetails output, in the non-parallel case. | 1220 // of the PrintGCDetails output, in the non-parallel case. |
1261 | 1221 |
1262 double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms); | 1222 double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms); |
1293 | 1253 |
1294 // TraceGen0Time and TraceGen1Time summary info updating. | 1254 // TraceGen0Time and TraceGen1Time summary info updating. |
1295 _all_pause_times_ms->add(elapsed_ms); | 1255 _all_pause_times_ms->add(elapsed_ms); |
1296 | 1256 |
1297 if (update_stats) { | 1257 if (update_stats) { |
1298 _recent_rs_scan_times_ms->add(scan_rs_time); | |
1299 _recent_pause_times_ms->add(elapsed_ms); | |
1300 _recent_rs_sizes->add(rs_size); | |
1301 | |
1302 _summary->record_total_time_ms(elapsed_ms); | 1258 _summary->record_total_time_ms(elapsed_ms); |
1303 _summary->record_other_time_ms(other_time_ms); | 1259 _summary->record_other_time_ms(other_time_ms); |
1304 | 1260 |
1305 MainBodySummary* body_summary = _summary->main_body_summary(); | 1261 MainBodySummary* body_summary = _summary->main_body_summary(); |
1306 assert(body_summary != NULL, "should not be null!"); | 1262 assert(body_summary != NULL, "should not be null!"); |
1340 assert((true || parallel) | 1296 assert((true || parallel) |
1341 || _g1->evacuation_failed() | 1297 || _g1->evacuation_failed() |
1342 || surviving_bytes <= _collection_set_bytes_used_before, | 1298 || surviving_bytes <= _collection_set_bytes_used_before, |
1343 "Or else negative collection!"); | 1299 "Or else negative collection!"); |
1344 | 1300 |
1345 _recent_CS_bytes_used_before->add(_collection_set_bytes_used_before); | |
1346 _recent_CS_bytes_surviving->add(surviving_bytes); | |
1347 | |
1348 // this is where we update the allocation rate of the application | 1301 // this is where we update the allocation rate of the application |
1349 double app_time_ms = | 1302 double app_time_ms = |
1350 (_cur_collection_start_sec * 1000.0 - _prev_collection_pause_end_ms); | 1303 (_cur_collection_start_sec * 1000.0 - _prev_collection_pause_end_ms); |
1351 if (app_time_ms < MIN_TIMER_GRANULARITY) { | 1304 if (app_time_ms < MIN_TIMER_GRANULARITY) { |
1352 // This usually happens due to the timer not having the required | 1305 // This usually happens due to the timer not having the required |
1353 // granularity. Some Linuxes are the usual culprits. | 1306 // granularity. Some Linuxes are the usual culprits. |
1354 // We'll just set it to something (arbitrarily) small. | 1307 // We'll just set it to something (arbitrarily) small. |
1355 app_time_ms = 1.0; | 1308 app_time_ms = 1.0; |
1356 } | 1309 } |
1357 size_t regions_allocated = | 1310 // We maintain the invariant that all objects allocated by mutator |
1358 (_region_num_young - _prev_region_num_young) + | 1311 // threads will be allocated out of eden regions. So, we can use |
1359 (_region_num_tenured - _prev_region_num_tenured); | 1312 // the eden region number allocated since the previous GC to |
1313 // calculate the application's allocate rate. The only exception | |
1314 // to that is humongous objects that are allocated separately. But | |
1315 // given that humongous object allocations do not really affect | |
1316 // either the pause's duration nor when the next pause will take | |
1317 // place we can safely ignore them here. | |
1318 size_t regions_allocated = eden_cset_region_length(); | |
1360 double alloc_rate_ms = (double) regions_allocated / app_time_ms; | 1319 double alloc_rate_ms = (double) regions_allocated / app_time_ms; |
1361 _alloc_rate_ms_seq->add(alloc_rate_ms); | 1320 _alloc_rate_ms_seq->add(alloc_rate_ms); |
1362 _prev_region_num_young = _region_num_young; | |
1363 _prev_region_num_tenured = _region_num_tenured; | |
1364 | 1321 |
1365 double interval_ms = | 1322 double interval_ms = |
1366 (end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0; | 1323 (end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0; |
1367 update_recent_gc_times(end_time_sec, elapsed_ms); | 1324 update_recent_gc_times(end_time_sec, elapsed_ms); |
1368 _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms; | 1325 _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms; |
1394 | 1351 |
1395 for (int i = 0; i < _aux_num; ++i) { | 1352 for (int i = 0; i < _aux_num; ++i) { |
1396 if (_cur_aux_times_set[i]) { | 1353 if (_cur_aux_times_set[i]) { |
1397 _all_aux_times_ms[i].add(_cur_aux_times_ms[i]); | 1354 _all_aux_times_ms[i].add(_cur_aux_times_ms[i]); |
1398 } | 1355 } |
1399 } | |
1400 | |
1401 | |
1402 if (G1PolicyVerbose > 1) { | |
1403 gclog_or_tty->print_cr(" Recording collection pause(%d)", _n_pauses); | |
1404 } | |
1405 | |
1406 if (G1PolicyVerbose > 1) { | |
1407 gclog_or_tty->print_cr(" ET: %10.6f ms (avg: %10.6f ms)\n" | |
1408 " ET-RS: %10.6f ms (avg: %10.6f ms)\n" | |
1409 " |RS|: " SIZE_FORMAT, | |
1410 elapsed_ms, recent_avg_time_for_pauses_ms(), | |
1411 scan_rs_time, recent_avg_time_for_rs_scan_ms(), | |
1412 rs_size); | |
1413 | |
1414 gclog_or_tty->print_cr(" Used at start: " SIZE_FORMAT"K" | |
1415 " At end " SIZE_FORMAT "K\n" | |
1416 " garbage : " SIZE_FORMAT "K" | |
1417 " of " SIZE_FORMAT "K\n" | |
1418 " survival : %6.2f%% (%6.2f%% avg)", | |
1419 _cur_collection_pause_used_at_start_bytes/K, | |
1420 _g1->used()/K, freed_bytes/K, | |
1421 _collection_set_bytes_used_before/K, | |
1422 survival_fraction*100.0, | |
1423 recent_avg_survival_fraction()*100.0); | |
1424 gclog_or_tty->print_cr(" Recent %% gc pause time: %6.2f", | |
1425 recent_avg_pause_time_ratio() * 100.0); | |
1426 } | 1356 } |
1427 | 1357 |
1428 // PrintGCDetails output | 1358 // PrintGCDetails output |
1429 if (PrintGCDetails) { | 1359 if (PrintGCDetails) { |
1430 bool print_marking_info = | 1360 bool print_marking_info = |
1574 } | 1504 } |
1575 | 1505 |
1576 _short_lived_surv_rate_group->start_adding_regions(); | 1506 _short_lived_surv_rate_group->start_adding_regions(); |
1577 // do that for any other surv rate groupsx | 1507 // do that for any other surv rate groupsx |
1578 | 1508 |
1579 // <NEW PREDICTION> | |
1580 | |
1581 if (update_stats) { | 1509 if (update_stats) { |
1582 double pause_time_ms = elapsed_ms; | 1510 double pause_time_ms = elapsed_ms; |
1583 | 1511 |
1584 size_t diff = 0; | 1512 size_t diff = 0; |
1585 if (_max_pending_cards >= _pending_cards) | 1513 if (_max_pending_cards >= _pending_cards) |
1629 double all_other_time_ms = pause_time_ms - | 1557 double all_other_time_ms = pause_time_ms - |
1630 (update_rs_time + scan_rs_time + obj_copy_time + | 1558 (update_rs_time + scan_rs_time + obj_copy_time + |
1631 _mark_closure_time_ms + termination_time); | 1559 _mark_closure_time_ms + termination_time); |
1632 | 1560 |
1633 double young_other_time_ms = 0.0; | 1561 double young_other_time_ms = 0.0; |
1634 if (_recorded_young_regions > 0) { | 1562 if (young_cset_region_length() > 0) { |
1635 young_other_time_ms = | 1563 young_other_time_ms = |
1636 _recorded_young_cset_choice_time_ms + | 1564 _recorded_young_cset_choice_time_ms + |
1637 _recorded_young_free_cset_time_ms; | 1565 _recorded_young_free_cset_time_ms; |
1638 _young_other_cost_per_region_ms_seq->add(young_other_time_ms / | 1566 _young_other_cost_per_region_ms_seq->add(young_other_time_ms / |
1639 (double) _recorded_young_regions); | 1567 (double) young_cset_region_length()); |
1640 } | 1568 } |
1641 double non_young_other_time_ms = 0.0; | 1569 double non_young_other_time_ms = 0.0; |
1642 if (_recorded_non_young_regions > 0) { | 1570 if (old_cset_region_length() > 0) { |
1643 non_young_other_time_ms = | 1571 non_young_other_time_ms = |
1644 _recorded_non_young_cset_choice_time_ms + | 1572 _recorded_non_young_cset_choice_time_ms + |
1645 _recorded_non_young_free_cset_time_ms; | 1573 _recorded_non_young_free_cset_time_ms; |
1646 | 1574 |
1647 _non_young_other_cost_per_region_ms_seq->add(non_young_other_time_ms / | 1575 _non_young_other_cost_per_region_ms_seq->add(non_young_other_time_ms / |
1648 (double) _recorded_non_young_regions); | 1576 (double) old_cset_region_length()); |
1649 } | 1577 } |
1650 | 1578 |
1651 double constant_other_time_ms = all_other_time_ms - | 1579 double constant_other_time_ms = all_other_time_ms - |
1652 (young_other_time_ms + non_young_other_time_ms); | 1580 (young_other_time_ms + non_young_other_time_ms); |
1653 _constant_other_time_ms_seq->add(constant_other_time_ms); | 1581 _constant_other_time_ms_seq->add(constant_other_time_ms); |
1657 survival_ratio = (double) _bytes_copied_during_gc / | 1585 survival_ratio = (double) _bytes_copied_during_gc / |
1658 (double) _bytes_in_collection_set_before_gc; | 1586 (double) _bytes_in_collection_set_before_gc; |
1659 } | 1587 } |
1660 | 1588 |
1661 _pending_cards_seq->add((double) _pending_cards); | 1589 _pending_cards_seq->add((double) _pending_cards); |
1662 _scanned_cards_seq->add((double) cards_scanned); | |
1663 _rs_lengths_seq->add((double) _max_rs_lengths); | 1590 _rs_lengths_seq->add((double) _max_rs_lengths); |
1664 | 1591 |
1665 double expensive_region_limit_ms = | 1592 double expensive_region_limit_ms = |
1666 (double) MaxGCPauseMillis - predict_constant_other_time_ms(); | 1593 (double) MaxGCPauseMillis - predict_constant_other_time_ms(); |
1667 if (expensive_region_limit_ms < 0.0) { | 1594 if (expensive_region_limit_ms < 0.0) { |
1668 // this means that the other time was predicted to be longer than | 1595 // this means that the other time was predicted to be longer than |
1669 // than the max pause time | 1596 // than the max pause time |
1670 expensive_region_limit_ms = (double) MaxGCPauseMillis; | 1597 expensive_region_limit_ms = (double) MaxGCPauseMillis; |
1671 } | 1598 } |
1672 _expensive_region_limit_ms = expensive_region_limit_ms; | 1599 _expensive_region_limit_ms = expensive_region_limit_ms; |
1673 | |
1674 if (PREDICTIONS_VERBOSE) { | |
1675 gclog_or_tty->print_cr(""); | |
1676 gclog_or_tty->print_cr("PREDICTIONS %1.4lf %d " | |
1677 "REGIONS %d %d %d " | |
1678 "PENDING_CARDS %d %d " | |
1679 "CARDS_SCANNED %d %d " | |
1680 "RS_LENGTHS %d %d " | |
1681 "RS_UPDATE %1.6lf %1.6lf RS_SCAN %1.6lf %1.6lf " | |
1682 "SURVIVAL_RATIO %1.6lf %1.6lf " | |
1683 "OBJECT_COPY %1.6lf %1.6lf OTHER_CONSTANT %1.6lf %1.6lf " | |
1684 "OTHER_YOUNG %1.6lf %1.6lf " | |
1685 "OTHER_NON_YOUNG %1.6lf %1.6lf " | |
1686 "VTIME_DIFF %1.6lf TERMINATION %1.6lf " | |
1687 "ELAPSED %1.6lf %1.6lf ", | |
1688 _cur_collection_start_sec, | |
1689 (!_last_young_gc_full) ? 2 : | |
1690 (last_pause_included_initial_mark) ? 1 : 0, | |
1691 _recorded_region_num, | |
1692 _recorded_young_regions, | |
1693 _recorded_non_young_regions, | |
1694 _predicted_pending_cards, _pending_cards, | |
1695 _predicted_cards_scanned, cards_scanned, | |
1696 _predicted_rs_lengths, _max_rs_lengths, | |
1697 _predicted_rs_update_time_ms, update_rs_time, | |
1698 _predicted_rs_scan_time_ms, scan_rs_time, | |
1699 _predicted_survival_ratio, survival_ratio, | |
1700 _predicted_object_copy_time_ms, obj_copy_time, | |
1701 _predicted_constant_other_time_ms, constant_other_time_ms, | |
1702 _predicted_young_other_time_ms, young_other_time_ms, | |
1703 _predicted_non_young_other_time_ms, | |
1704 non_young_other_time_ms, | |
1705 _vtime_diff_ms, termination_time, | |
1706 _predicted_pause_time_ms, elapsed_ms); | |
1707 } | |
1708 | |
1709 if (G1PolicyVerbose > 0) { | |
1710 gclog_or_tty->print_cr("Pause Time, predicted: %1.4lfms (predicted %s), actual: %1.4lfms", | |
1711 _predicted_pause_time_ms, | |
1712 (_within_target) ? "within" : "outside", | |
1713 elapsed_ms); | |
1714 } | |
1715 | |
1716 } | 1600 } |
1717 | 1601 |
1718 _in_marking_window = new_in_marking_window; | 1602 _in_marking_window = new_in_marking_window; |
1719 _in_marking_window_im = new_in_marking_window_im; | 1603 _in_marking_window_im = new_in_marking_window_im; |
1720 _free_regions_at_end_of_collection = _g1->free_regions(); | 1604 _free_regions_at_end_of_collection = _g1->free_regions(); |
1721 update_young_list_target_length(); | 1605 update_young_list_target_length(); |
1722 | 1606 |
1723 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. | 1607 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. |
1724 double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; | 1608 double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; |
1725 adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); | 1609 adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); |
1726 // </NEW PREDICTION> | |
1727 | 1610 |
1728 assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end."); | 1611 assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end."); |
1729 } | 1612 } |
1730 | 1613 |
1731 #define EXT_SIZE_FORMAT "%d%s" | 1614 #define EXT_SIZE_FORMAT "%d%s" |
1766 _cur_collection_pause_used_at_start_bytes, | 1649 _cur_collection_pause_used_at_start_bytes, |
1767 _g1->used(), _g1->capacity()); | 1650 _g1->used(), _g1->capacity()); |
1768 } | 1651 } |
1769 } | 1652 } |
1770 | 1653 |
1771 // <NEW PREDICTION> | |
1772 | |
1773 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time, | 1654 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time, |
1774 double update_rs_processed_buffers, | 1655 double update_rs_processed_buffers, |
1775 double goal_ms) { | 1656 double goal_ms) { |
1776 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | 1657 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); |
1777 ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine(); | 1658 ConcurrentG1Refine *cg1r = G1CollectedHeap::heap()->concurrent_g1_refine(); |
1903 | 1784 |
1904 return bytes_to_copy; | 1785 return bytes_to_copy; |
1905 } | 1786 } |
1906 | 1787 |
1907 void | 1788 void |
1908 G1CollectorPolicy::start_recording_regions() { | 1789 G1CollectorPolicy::init_cset_region_lengths(size_t eden_cset_region_length, |
1909 _recorded_rs_lengths = 0; | 1790 size_t survivor_cset_region_length) { |
1910 _recorded_young_regions = 0; | 1791 _eden_cset_region_length = eden_cset_region_length; |
1911 _recorded_non_young_regions = 0; | 1792 _survivor_cset_region_length = survivor_cset_region_length; |
1912 | 1793 _old_cset_region_length = 0; |
1913 #if PREDICTIONS_VERBOSE | |
1914 _recorded_marked_bytes = 0; | |
1915 _recorded_young_bytes = 0; | |
1916 _predicted_bytes_to_copy = 0; | |
1917 _predicted_rs_lengths = 0; | |
1918 _predicted_cards_scanned = 0; | |
1919 #endif // PREDICTIONS_VERBOSE | |
1920 } | |
1921 | |
1922 void | |
1923 G1CollectorPolicy::record_cset_region_info(HeapRegion* hr, bool young) { | |
1924 #if PREDICTIONS_VERBOSE | |
1925 if (!young) { | |
1926 _recorded_marked_bytes += hr->max_live_bytes(); | |
1927 } | |
1928 _predicted_bytes_to_copy += predict_bytes_to_copy(hr); | |
1929 #endif // PREDICTIONS_VERBOSE | |
1930 | |
1931 size_t rs_length = hr->rem_set()->occupied(); | |
1932 _recorded_rs_lengths += rs_length; | |
1933 } | |
1934 | |
1935 void | |
1936 G1CollectorPolicy::record_non_young_cset_region(HeapRegion* hr) { | |
1937 assert(!hr->is_young(), "should not call this"); | |
1938 ++_recorded_non_young_regions; | |
1939 record_cset_region_info(hr, false); | |
1940 } | |
1941 | |
1942 void | |
1943 G1CollectorPolicy::set_recorded_young_regions(size_t n_regions) { | |
1944 _recorded_young_regions = n_regions; | |
1945 } | |
1946 | |
1947 void G1CollectorPolicy::set_recorded_young_bytes(size_t bytes) { | |
1948 #if PREDICTIONS_VERBOSE | |
1949 _recorded_young_bytes = bytes; | |
1950 #endif // PREDICTIONS_VERBOSE | |
1951 } | 1794 } |
1952 | 1795 |
1953 void G1CollectorPolicy::set_recorded_rs_lengths(size_t rs_lengths) { | 1796 void G1CollectorPolicy::set_recorded_rs_lengths(size_t rs_lengths) { |
1954 _recorded_rs_lengths = rs_lengths; | 1797 _recorded_rs_lengths = rs_lengths; |
1955 } | |
1956 | |
1957 void G1CollectorPolicy::set_predicted_bytes_to_copy(size_t bytes) { | |
1958 _predicted_bytes_to_copy = bytes; | |
1959 } | |
1960 | |
1961 void | |
1962 G1CollectorPolicy::end_recording_regions() { | |
1963 // The _predicted_pause_time_ms field is referenced in code | |
1964 // not under PREDICTIONS_VERBOSE. Let's initialize it. | |
1965 _predicted_pause_time_ms = -1.0; | |
1966 | |
1967 #if PREDICTIONS_VERBOSE | |
1968 _predicted_pending_cards = predict_pending_cards(); | |
1969 _predicted_rs_lengths = _recorded_rs_lengths + predict_rs_length_diff(); | |
1970 if (full_young_gcs()) | |
1971 _predicted_cards_scanned += predict_young_card_num(_predicted_rs_lengths); | |
1972 else | |
1973 _predicted_cards_scanned += | |
1974 predict_non_young_card_num(_predicted_rs_lengths); | |
1975 _recorded_region_num = _recorded_young_regions + _recorded_non_young_regions; | |
1976 | |
1977 _predicted_rs_update_time_ms = | |
1978 predict_rs_update_time_ms(_g1->pending_card_num()); | |
1979 _predicted_rs_scan_time_ms = | |
1980 predict_rs_scan_time_ms(_predicted_cards_scanned); | |
1981 _predicted_object_copy_time_ms = | |
1982 predict_object_copy_time_ms(_predicted_bytes_to_copy); | |
1983 _predicted_constant_other_time_ms = | |
1984 predict_constant_other_time_ms(); | |
1985 _predicted_young_other_time_ms = | |
1986 predict_young_other_time_ms(_recorded_young_regions); | |
1987 _predicted_non_young_other_time_ms = | |
1988 predict_non_young_other_time_ms(_recorded_non_young_regions); | |
1989 | |
1990 _predicted_pause_time_ms = | |
1991 _predicted_rs_update_time_ms + | |
1992 _predicted_rs_scan_time_ms + | |
1993 _predicted_object_copy_time_ms + | |
1994 _predicted_constant_other_time_ms + | |
1995 _predicted_young_other_time_ms + | |
1996 _predicted_non_young_other_time_ms; | |
1997 #endif // PREDICTIONS_VERBOSE | |
1998 } | 1798 } |
1999 | 1799 |
2000 void G1CollectorPolicy::check_if_region_is_too_expensive(double | 1800 void G1CollectorPolicy::check_if_region_is_too_expensive(double |
2001 predicted_time_ms) { | 1801 predicted_time_ms) { |
2002 // I don't think we need to do this when in young GC mode since | 1802 // I don't think we need to do this when in young GC mode since |
2011 // no point in doing another partial one | 1811 // no point in doing another partial one |
2012 _should_revert_to_full_young_gcs = true; | 1812 _should_revert_to_full_young_gcs = true; |
2013 } | 1813 } |
2014 } | 1814 } |
2015 | 1815 |
2016 // </NEW PREDICTION> | |
2017 | |
2018 | |
2019 void G1CollectorPolicy::update_recent_gc_times(double end_time_sec, | 1816 void G1CollectorPolicy::update_recent_gc_times(double end_time_sec, |
2020 double elapsed_ms) { | 1817 double elapsed_ms) { |
2021 _recent_gc_times_ms->add(elapsed_ms); | 1818 _recent_gc_times_ms->add(elapsed_ms); |
2022 _recent_prev_end_times_for_all_gcs_sec->add(end_time_sec); | 1819 _recent_prev_end_times_for_all_gcs_sec->add(end_time_sec); |
2023 _prev_collection_pause_end_ms = end_time_sec * 1000.0; | 1820 _prev_collection_pause_end_ms = end_time_sec * 1000.0; |
2024 } | |
2025 | |
2026 double G1CollectorPolicy::recent_avg_time_for_pauses_ms() { | |
2027 if (_recent_pause_times_ms->num() == 0) { | |
2028 return (double) MaxGCPauseMillis; | |
2029 } | |
2030 return _recent_pause_times_ms->avg(); | |
2031 } | |
2032 | |
2033 double G1CollectorPolicy::recent_avg_time_for_rs_scan_ms() { | |
2034 if (_recent_rs_scan_times_ms->num() == 0) { | |
2035 return (double)MaxGCPauseMillis/3.0; | |
2036 } | |
2037 return _recent_rs_scan_times_ms->avg(); | |
2038 } | |
2039 | |
2040 int G1CollectorPolicy::number_of_recent_gcs() { | |
2041 assert(_recent_rs_scan_times_ms->num() == | |
2042 _recent_pause_times_ms->num(), "Sequence out of sync"); | |
2043 assert(_recent_pause_times_ms->num() == | |
2044 _recent_CS_bytes_used_before->num(), "Sequence out of sync"); | |
2045 assert(_recent_CS_bytes_used_before->num() == | |
2046 _recent_CS_bytes_surviving->num(), "Sequence out of sync"); | |
2047 | |
2048 return _recent_pause_times_ms->num(); | |
2049 } | |
2050 | |
2051 double G1CollectorPolicy::recent_avg_survival_fraction() { | |
2052 return recent_avg_survival_fraction_work(_recent_CS_bytes_surviving, | |
2053 _recent_CS_bytes_used_before); | |
2054 } | |
2055 | |
2056 double G1CollectorPolicy::last_survival_fraction() { | |
2057 return last_survival_fraction_work(_recent_CS_bytes_surviving, | |
2058 _recent_CS_bytes_used_before); | |
2059 } | |
2060 | |
2061 double | |
2062 G1CollectorPolicy::recent_avg_survival_fraction_work(TruncatedSeq* surviving, | |
2063 TruncatedSeq* before) { | |
2064 assert(surviving->num() == before->num(), "Sequence out of sync"); | |
2065 if (before->sum() > 0.0) { | |
2066 double recent_survival_rate = surviving->sum() / before->sum(); | |
2067 // We exempt parallel collection from this check because Alloc Buffer | |
2068 // fragmentation can produce negative collections. | |
2069 // Further, we're now always doing parallel collection. But I'm still | |
2070 // leaving this here as a placeholder for a more precise assertion later. | |
2071 // (DLD, 10/05.) | |
2072 assert((true || G1CollectedHeap::use_parallel_gc_threads()) || | |
2073 _g1->evacuation_failed() || | |
2074 recent_survival_rate <= 1.0, "Or bad frac"); | |
2075 return recent_survival_rate; | |
2076 } else { | |
2077 return 1.0; // Be conservative. | |
2078 } | |
2079 } | |
2080 | |
2081 double | |
2082 G1CollectorPolicy::last_survival_fraction_work(TruncatedSeq* surviving, | |
2083 TruncatedSeq* before) { | |
2084 assert(surviving->num() == before->num(), "Sequence out of sync"); | |
2085 if (surviving->num() > 0 && before->last() > 0.0) { | |
2086 double last_survival_rate = surviving->last() / before->last(); | |
2087 // We exempt parallel collection from this check because Alloc Buffer | |
2088 // fragmentation can produce negative collections. | |
2089 // Further, we're now always doing parallel collection. But I'm still | |
2090 // leaving this here as a placeholder for a more precise assertion later. | |
2091 // (DLD, 10/05.) | |
2092 assert((true || G1CollectedHeap::use_parallel_gc_threads()) || | |
2093 last_survival_rate <= 1.0, "Or bad frac"); | |
2094 return last_survival_rate; | |
2095 } else { | |
2096 return 1.0; | |
2097 } | |
2098 } | |
2099 | |
2100 static const int survival_min_obs = 5; | |
2101 static double survival_min_obs_limits[] = { 0.9, 0.7, 0.5, 0.3, 0.1 }; | |
2102 static const double min_survival_rate = 0.1; | |
2103 | |
2104 double | |
2105 G1CollectorPolicy::conservative_avg_survival_fraction_work(double avg, | |
2106 double latest) { | |
2107 double res = avg; | |
2108 if (number_of_recent_gcs() < survival_min_obs) { | |
2109 res = MAX2(res, survival_min_obs_limits[number_of_recent_gcs()]); | |
2110 } | |
2111 res = MAX2(res, latest); | |
2112 res = MAX2(res, min_survival_rate); | |
2113 // In the parallel case, LAB fragmentation can produce "negative | |
2114 // collections"; so can evac failure. Cap at 1.0 | |
2115 res = MIN2(res, 1.0); | |
2116 return res; | |
2117 } | 1821 } |
2118 | 1822 |
2119 size_t G1CollectorPolicy::expansion_amount() { | 1823 size_t G1CollectorPolicy::expansion_amount() { |
2120 double recent_gc_overhead = recent_avg_pause_time_ratio() * 100.0; | 1824 double recent_gc_overhead = recent_avg_pause_time_ratio() * 100.0; |
2121 double threshold = _gc_overhead_perc; | 1825 double threshold = _gc_overhead_perc; |
2329 char buffer[96]; | 2033 char buffer[96]; |
2330 sprintf(buffer, "Aux%d", i); | 2034 sprintf(buffer, "Aux%d", i); |
2331 print_summary_sd(0, buffer, &_all_aux_times_ms[i]); | 2035 print_summary_sd(0, buffer, &_all_aux_times_ms[i]); |
2332 } | 2036 } |
2333 } | 2037 } |
2334 | |
2335 size_t all_region_num = _region_num_young + _region_num_tenured; | |
2336 gclog_or_tty->print_cr(" New Regions %8d, Young %8d (%6.2lf%%), " | |
2337 "Tenured %8d (%6.2lf%%)", | |
2338 all_region_num, | |
2339 _region_num_young, | |
2340 (double) _region_num_young / (double) all_region_num * 100.0, | |
2341 _region_num_tenured, | |
2342 (double) _region_num_tenured / (double) all_region_num * 100.0); | |
2343 } | 2038 } |
2344 if (TraceGen1Time) { | 2039 if (TraceGen1Time) { |
2345 if (_all_full_gc_times_ms->num() > 0) { | 2040 if (_all_full_gc_times_ms->num() > 0) { |
2346 gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s", | 2041 gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s", |
2347 _all_full_gc_times_ms->num(), | 2042 _all_full_gc_times_ms->num(), |
2357 void G1CollectorPolicy::print_yg_surv_rate_info() const { | 2052 void G1CollectorPolicy::print_yg_surv_rate_info() const { |
2358 #ifndef PRODUCT | 2053 #ifndef PRODUCT |
2359 _short_lived_surv_rate_group->print_surv_rate_summary(); | 2054 _short_lived_surv_rate_group->print_surv_rate_summary(); |
2360 // add this call for any other surv rate groups | 2055 // add this call for any other surv rate groups |
2361 #endif // PRODUCT | 2056 #endif // PRODUCT |
2362 } | |
2363 | |
2364 void G1CollectorPolicy::update_region_num(bool young) { | |
2365 if (young) { | |
2366 ++_region_num_young; | |
2367 } else { | |
2368 ++_region_num_tenured; | |
2369 } | |
2370 } | 2057 } |
2371 | 2058 |
2372 #ifndef PRODUCT | 2059 #ifndef PRODUCT |
2373 // for debugging, bit of a hack... | 2060 // for debugging, bit of a hack... |
2374 static char* | 2061 static char* |
2680 _prev_collection_pause_end_ms += elapsed_time_ms; | 2367 _prev_collection_pause_end_ms += elapsed_time_ms; |
2681 _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, true); | 2368 _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, true); |
2682 } | 2369 } |
2683 | 2370 |
2684 // Add the heap region at the head of the non-incremental collection set | 2371 // Add the heap region at the head of the non-incremental collection set |
2685 void G1CollectorPolicy:: | 2372 void G1CollectorPolicy::add_old_region_to_cset(HeapRegion* hr) { |
2686 add_to_collection_set(HeapRegion* hr) { | |
2687 assert(_inc_cset_build_state == Active, "Precondition"); | 2373 assert(_inc_cset_build_state == Active, "Precondition"); |
2688 assert(!hr->is_young(), "non-incremental add of young region"); | 2374 assert(!hr->is_young(), "non-incremental add of young region"); |
2689 | 2375 |
2690 if (_g1->mark_in_progress()) | 2376 if (_g1->mark_in_progress()) |
2691 _g1->concurrent_mark()->registerCSetRegion(hr); | 2377 _g1->concurrent_mark()->registerCSetRegion(hr); |
2692 | 2378 |
2693 assert(!hr->in_collection_set(), "should not already be in the CSet"); | 2379 assert(!hr->in_collection_set(), "should not already be in the CSet"); |
2694 hr->set_in_collection_set(true); | 2380 hr->set_in_collection_set(true); |
2695 hr->set_next_in_collection_set(_collection_set); | 2381 hr->set_next_in_collection_set(_collection_set); |
2696 _collection_set = hr; | 2382 _collection_set = hr; |
2697 _collection_set_size++; | |
2698 _collection_set_bytes_used_before += hr->used(); | 2383 _collection_set_bytes_used_before += hr->used(); |
2699 _g1->register_region_with_in_cset_fast_test(hr); | 2384 _g1->register_region_with_in_cset_fast_test(hr); |
2385 size_t rs_length = hr->rem_set()->occupied(); | |
2386 _recorded_rs_lengths += rs_length; | |
2387 _old_cset_region_length += 1; | |
2700 } | 2388 } |
2701 | 2389 |
2702 // Initialize the per-collection-set information | 2390 // Initialize the per-collection-set information |
2703 void G1CollectorPolicy::start_incremental_cset_building() { | 2391 void G1CollectorPolicy::start_incremental_cset_building() { |
2704 assert(_inc_cset_build_state == Inactive, "Precondition"); | 2392 assert(_inc_cset_build_state == Inactive, "Precondition"); |
2705 | 2393 |
2706 _inc_cset_head = NULL; | 2394 _inc_cset_head = NULL; |
2707 _inc_cset_tail = NULL; | 2395 _inc_cset_tail = NULL; |
2708 _inc_cset_size = 0; | |
2709 _inc_cset_bytes_used_before = 0; | 2396 _inc_cset_bytes_used_before = 0; |
2710 | 2397 |
2711 _inc_cset_young_index = 0; | |
2712 | |
2713 _inc_cset_max_finger = 0; | 2398 _inc_cset_max_finger = 0; |
2714 _inc_cset_recorded_young_bytes = 0; | |
2715 _inc_cset_recorded_rs_lengths = 0; | 2399 _inc_cset_recorded_rs_lengths = 0; |
2716 _inc_cset_predicted_elapsed_time_ms = 0; | 2400 _inc_cset_predicted_elapsed_time_ms = 0; |
2717 _inc_cset_predicted_bytes_to_copy = 0; | |
2718 _inc_cset_build_state = Active; | 2401 _inc_cset_build_state = Active; |
2719 } | 2402 } |
2720 | 2403 |
2721 void G1CollectorPolicy::add_to_incremental_cset_info(HeapRegion* hr, size_t rs_length) { | 2404 void G1CollectorPolicy::add_to_incremental_cset_info(HeapRegion* hr, size_t rs_length) { |
2722 // This routine is used when: | 2405 // This routine is used when: |
2743 // in the heap region in case we have to remove this region from | 2426 // in the heap region in case we have to remove this region from |
2744 // the incremental collection set, or it is updated by the | 2427 // the incremental collection set, or it is updated by the |
2745 // rset sampling code | 2428 // rset sampling code |
2746 hr->set_recorded_rs_length(rs_length); | 2429 hr->set_recorded_rs_length(rs_length); |
2747 hr->set_predicted_elapsed_time_ms(region_elapsed_time_ms); | 2430 hr->set_predicted_elapsed_time_ms(region_elapsed_time_ms); |
2748 | |
2749 #if PREDICTIONS_VERBOSE | |
2750 size_t bytes_to_copy = predict_bytes_to_copy(hr); | |
2751 _inc_cset_predicted_bytes_to_copy += bytes_to_copy; | |
2752 | |
2753 // Record the number of bytes used in this region | |
2754 _inc_cset_recorded_young_bytes += used_bytes; | |
2755 | |
2756 // Cache the values we have added to the aggregated informtion | |
2757 // in the heap region in case we have to remove this region from | |
2758 // the incremental collection set, or it is updated by the | |
2759 // rset sampling code | |
2760 hr->set_predicted_bytes_to_copy(bytes_to_copy); | |
2761 #endif // PREDICTIONS_VERBOSE | |
2762 } | 2431 } |
2763 | 2432 |
2764 void G1CollectorPolicy::remove_from_incremental_cset_info(HeapRegion* hr) { | 2433 void G1CollectorPolicy::remove_from_incremental_cset_info(HeapRegion* hr) { |
2765 // This routine is currently only called as part of the updating of | 2434 // This routine is currently only called as part of the updating of |
2766 // existing policy information for regions in the incremental cset that | 2435 // existing policy information for regions in the incremental cset that |
2782 _inc_cset_bytes_used_before -= used_bytes; | 2451 _inc_cset_bytes_used_before -= used_bytes; |
2783 | 2452 |
2784 // Clear the values cached in the heap region | 2453 // Clear the values cached in the heap region |
2785 hr->set_recorded_rs_length(0); | 2454 hr->set_recorded_rs_length(0); |
2786 hr->set_predicted_elapsed_time_ms(0); | 2455 hr->set_predicted_elapsed_time_ms(0); |
2787 | |
2788 #if PREDICTIONS_VERBOSE | |
2789 size_t old_predicted_bytes_to_copy = hr->predicted_bytes_to_copy(); | |
2790 _inc_cset_predicted_bytes_to_copy -= old_predicted_bytes_to_copy; | |
2791 | |
2792 // Subtract the number of bytes used in this region | |
2793 _inc_cset_recorded_young_bytes -= used_bytes; | |
2794 | |
2795 // Clear the values cached in the heap region | |
2796 hr->set_predicted_bytes_to_copy(0); | |
2797 #endif // PREDICTIONS_VERBOSE | |
2798 } | 2456 } |
2799 | 2457 |
2800 void G1CollectorPolicy::update_incremental_cset_info(HeapRegion* hr, size_t new_rs_length) { | 2458 void G1CollectorPolicy::update_incremental_cset_info(HeapRegion* hr, size_t new_rs_length) { |
2801 // Update the collection set information that is dependent on the new RS length | 2459 // Update the collection set information that is dependent on the new RS length |
2802 assert(hr->is_young(), "Precondition"); | 2460 assert(hr->is_young(), "Precondition"); |
2804 remove_from_incremental_cset_info(hr); | 2462 remove_from_incremental_cset_info(hr); |
2805 add_to_incremental_cset_info(hr, new_rs_length); | 2463 add_to_incremental_cset_info(hr, new_rs_length); |
2806 } | 2464 } |
2807 | 2465 |
2808 void G1CollectorPolicy::add_region_to_incremental_cset_common(HeapRegion* hr) { | 2466 void G1CollectorPolicy::add_region_to_incremental_cset_common(HeapRegion* hr) { |
2809 assert( hr->is_young(), "invariant"); | 2467 assert(hr->is_young(), "invariant"); |
2810 assert( hr->young_index_in_cset() == -1, "invariant" ); | 2468 assert(hr->young_index_in_cset() > -1, "should have already been set"); |
2811 assert(_inc_cset_build_state == Active, "Precondition"); | 2469 assert(_inc_cset_build_state == Active, "Precondition"); |
2812 | 2470 |
2813 // We need to clear and set the cached recorded/cached collection set | 2471 // We need to clear and set the cached recorded/cached collection set |
2814 // information in the heap region here (before the region gets added | 2472 // information in the heap region here (before the region gets added |
2815 // to the collection set). An individual heap region's cached values | 2473 // to the collection set). An individual heap region's cached values |
2825 | 2483 |
2826 assert(!hr->in_collection_set(), "invariant"); | 2484 assert(!hr->in_collection_set(), "invariant"); |
2827 hr->set_in_collection_set(true); | 2485 hr->set_in_collection_set(true); |
2828 assert( hr->next_in_collection_set() == NULL, "invariant"); | 2486 assert( hr->next_in_collection_set() == NULL, "invariant"); |
2829 | 2487 |
2830 _inc_cset_size++; | |
2831 _g1->register_region_with_in_cset_fast_test(hr); | 2488 _g1->register_region_with_in_cset_fast_test(hr); |
2832 | |
2833 hr->set_young_index_in_cset((int) _inc_cset_young_index); | |
2834 ++_inc_cset_young_index; | |
2835 } | 2489 } |
2836 | 2490 |
2837 // Add the region at the RHS of the incremental cset | 2491 // Add the region at the RHS of the incremental cset |
2838 void G1CollectorPolicy::add_region_to_incremental_cset_rhs(HeapRegion* hr) { | 2492 void G1CollectorPolicy::add_region_to_incremental_cset_rhs(HeapRegion* hr) { |
2839 // We should only ever be appending survivors at the end of a pause | 2493 // We should only ever be appending survivors at the end of a pause |
2897 // Set this here - in case we're not doing young collections. | 2551 // Set this here - in case we're not doing young collections. |
2898 double non_young_start_time_sec = os::elapsedTime(); | 2552 double non_young_start_time_sec = os::elapsedTime(); |
2899 | 2553 |
2900 YoungList* young_list = _g1->young_list(); | 2554 YoungList* young_list = _g1->young_list(); |
2901 | 2555 |
2902 start_recording_regions(); | |
2903 | |
2904 guarantee(target_pause_time_ms > 0.0, | 2556 guarantee(target_pause_time_ms > 0.0, |
2905 err_msg("target_pause_time_ms = %1.6lf should be positive", | 2557 err_msg("target_pause_time_ms = %1.6lf should be positive", |
2906 target_pause_time_ms)); | 2558 target_pause_time_ms)); |
2907 guarantee(_collection_set == NULL, "Precondition"); | 2559 guarantee(_collection_set == NULL, "Precondition"); |
2908 | 2560 |
2921 // the 10% and 50% values are arbitrary... | 2573 // the 10% and 50% values are arbitrary... |
2922 double threshold = 0.10 * target_pause_time_ms; | 2574 double threshold = 0.10 * target_pause_time_ms; |
2923 if (time_remaining_ms < threshold) { | 2575 if (time_remaining_ms < threshold) { |
2924 double prev_time_remaining_ms = time_remaining_ms; | 2576 double prev_time_remaining_ms = time_remaining_ms; |
2925 time_remaining_ms = 0.50 * target_pause_time_ms; | 2577 time_remaining_ms = 0.50 * target_pause_time_ms; |
2926 _within_target = false; | |
2927 ergo_verbose3(ErgoCSetConstruction, | 2578 ergo_verbose3(ErgoCSetConstruction, |
2928 "adjust remaining time", | 2579 "adjust remaining time", |
2929 ergo_format_reason("remaining time lower than threshold") | 2580 ergo_format_reason("remaining time lower than threshold") |
2930 ergo_format_ms("remaining time") | 2581 ergo_format_ms("remaining time") |
2931 ergo_format_ms("threshold") | 2582 ergo_format_ms("threshold") |
2932 ergo_format_ms("adjusted remaining time"), | 2583 ergo_format_ms("adjusted remaining time"), |
2933 prev_time_remaining_ms, threshold, time_remaining_ms); | 2584 prev_time_remaining_ms, threshold, time_remaining_ms); |
2934 } else { | |
2935 _within_target = true; | |
2936 } | 2585 } |
2937 | 2586 |
2938 size_t expansion_bytes = _g1->expansion_regions() * HeapRegion::GrainBytes; | 2587 size_t expansion_bytes = _g1->expansion_regions() * HeapRegion::GrainBytes; |
2939 | 2588 |
2940 HeapRegion* hr; | 2589 HeapRegion* hr; |
2941 double young_start_time_sec = os::elapsedTime(); | 2590 double young_start_time_sec = os::elapsedTime(); |
2942 | 2591 |
2943 _collection_set_bytes_used_before = 0; | 2592 _collection_set_bytes_used_before = 0; |
2944 _collection_set_size = 0; | |
2945 _young_cset_length = 0; | |
2946 _last_young_gc_full = full_young_gcs() ? true : false; | 2593 _last_young_gc_full = full_young_gcs() ? true : false; |
2947 | 2594 |
2948 if (_last_young_gc_full) { | 2595 if (_last_young_gc_full) { |
2949 ++_full_young_pause_num; | 2596 ++_full_young_pause_num; |
2950 } else { | 2597 } else { |
2953 | 2600 |
2954 // The young list is laid with the survivor regions from the previous | 2601 // The young list is laid with the survivor regions from the previous |
2955 // pause are appended to the RHS of the young list, i.e. | 2602 // pause are appended to the RHS of the young list, i.e. |
2956 // [Newly Young Regions ++ Survivors from last pause]. | 2603 // [Newly Young Regions ++ Survivors from last pause]. |
2957 | 2604 |
2958 size_t survivor_region_num = young_list->survivor_length(); | 2605 size_t survivor_region_length = young_list->survivor_length(); |
2959 size_t eden_region_num = young_list->length() - survivor_region_num; | 2606 size_t eden_region_length = young_list->length() - survivor_region_length; |
2960 size_t old_region_num = 0; | 2607 init_cset_region_lengths(eden_region_length, survivor_region_length); |
2961 hr = young_list->first_survivor_region(); | 2608 hr = young_list->first_survivor_region(); |
2962 while (hr != NULL) { | 2609 while (hr != NULL) { |
2963 assert(hr->is_survivor(), "badly formed young list"); | 2610 assert(hr->is_survivor(), "badly formed young list"); |
2964 hr->set_young(); | 2611 hr->set_young(); |
2965 hr = hr->get_next_young_region(); | 2612 hr = hr->get_next_young_region(); |
2969 young_list->clear_survivors(); | 2616 young_list->clear_survivors(); |
2970 | 2617 |
2971 if (_g1->mark_in_progress()) | 2618 if (_g1->mark_in_progress()) |
2972 _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger); | 2619 _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger); |
2973 | 2620 |
2974 _young_cset_length = _inc_cset_young_index; | |
2975 _collection_set = _inc_cset_head; | 2621 _collection_set = _inc_cset_head; |
2976 _collection_set_size = _inc_cset_size; | |
2977 _collection_set_bytes_used_before = _inc_cset_bytes_used_before; | 2622 _collection_set_bytes_used_before = _inc_cset_bytes_used_before; |
2978 time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms; | 2623 time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms; |
2979 predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; | 2624 predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; |
2980 | 2625 |
2981 ergo_verbose3(ErgoCSetConstruction | ErgoHigh, | 2626 ergo_verbose3(ErgoCSetConstruction | ErgoHigh, |
2982 "add young regions to CSet", | 2627 "add young regions to CSet", |
2983 ergo_format_region("eden") | 2628 ergo_format_region("eden") |
2984 ergo_format_region("survivors") | 2629 ergo_format_region("survivors") |
2985 ergo_format_ms("predicted young region time"), | 2630 ergo_format_ms("predicted young region time"), |
2986 eden_region_num, survivor_region_num, | 2631 eden_region_length, survivor_region_length, |
2987 _inc_cset_predicted_elapsed_time_ms); | 2632 _inc_cset_predicted_elapsed_time_ms); |
2988 | 2633 |
2989 // The number of recorded young regions is the incremental | 2634 // The number of recorded young regions is the incremental |
2990 // collection set's current size | 2635 // collection set's current size |
2991 set_recorded_young_regions(_inc_cset_size); | |
2992 set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths); | 2636 set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths); |
2993 set_recorded_young_bytes(_inc_cset_recorded_young_bytes); | |
2994 #if PREDICTIONS_VERBOSE | |
2995 set_predicted_bytes_to_copy(_inc_cset_predicted_bytes_to_copy); | |
2996 #endif // PREDICTIONS_VERBOSE | |
2997 | |
2998 assert(_inc_cset_size == young_list->length(), "Invariant"); | |
2999 | 2637 |
3000 double young_end_time_sec = os::elapsedTime(); | 2638 double young_end_time_sec = os::elapsedTime(); |
3001 _recorded_young_cset_choice_time_ms = | 2639 _recorded_young_cset_choice_time_ms = |
3002 (young_end_time_sec - young_start_time_sec) * 1000.0; | 2640 (young_end_time_sec - young_start_time_sec) * 1000.0; |
3003 | 2641 |
3007 if (!full_young_gcs()) { | 2645 if (!full_young_gcs()) { |
3008 bool should_continue = true; | 2646 bool should_continue = true; |
3009 NumberSeq seq; | 2647 NumberSeq seq; |
3010 double avg_prediction = 100000000000000000.0; // something very large | 2648 double avg_prediction = 100000000000000000.0; // something very large |
3011 | 2649 |
3012 size_t prev_collection_set_size = _collection_set_size; | |
3013 double prev_predicted_pause_time_ms = predicted_pause_time_ms; | 2650 double prev_predicted_pause_time_ms = predicted_pause_time_ms; |
3014 do { | 2651 do { |
2652 // Note that add_old_region_to_cset() increments the | |
2653 // _old_cset_region_length field and cset_region_length() returns the | |
2654 // sum of _eden_cset_region_length, _survivor_cset_region_length, and | |
2655 // _old_cset_region_length. So, as old regions are added to the | |
2656 // CSet, _old_cset_region_length will be incremented and | |
2657 // cset_region_length(), which is used below, will always reflect | |
2658 // the the total number of regions added up to this point to the CSet. | |
2659 | |
3015 hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms, | 2660 hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms, |
3016 avg_prediction); | 2661 avg_prediction); |
3017 if (hr != NULL) { | 2662 if (hr != NULL) { |
3018 _g1->old_set_remove(hr); | 2663 _g1->old_set_remove(hr); |
3019 double predicted_time_ms = predict_region_elapsed_time_ms(hr, false); | 2664 double predicted_time_ms = predict_region_elapsed_time_ms(hr, false); |
3020 time_remaining_ms -= predicted_time_ms; | 2665 time_remaining_ms -= predicted_time_ms; |
3021 predicted_pause_time_ms += predicted_time_ms; | 2666 predicted_pause_time_ms += predicted_time_ms; |
3022 add_to_collection_set(hr); | 2667 add_old_region_to_cset(hr); |
3023 record_non_young_cset_region(hr); | |
3024 seq.add(predicted_time_ms); | 2668 seq.add(predicted_time_ms); |
3025 avg_prediction = seq.avg() + seq.sd(); | 2669 avg_prediction = seq.avg() + seq.sd(); |
3026 } | 2670 } |
3027 | 2671 |
3028 should_continue = true; | 2672 should_continue = true; |
3039 ergo_format_ms("remaining time"), | 2683 ergo_format_ms("remaining time"), |
3040 time_remaining_ms); | 2684 time_remaining_ms); |
3041 should_continue = false; | 2685 should_continue = false; |
3042 } | 2686 } |
3043 } else { | 2687 } else { |
3044 if (_collection_set_size >= _young_list_fixed_length) { | 2688 if (cset_region_length() >= _young_list_fixed_length) { |
3045 ergo_verbose2(ErgoCSetConstruction, | 2689 ergo_verbose2(ErgoCSetConstruction, |
3046 "stop adding old regions to CSet", | 2690 "stop adding old regions to CSet", |
3047 ergo_format_reason("CSet length reached target") | 2691 ergo_format_reason("CSet length reached target") |
3048 ergo_format_region("CSet") | 2692 ergo_format_region("CSet") |
3049 ergo_format_region("young target"), | 2693 ergo_format_region("young target"), |
3050 _collection_set_size, _young_list_fixed_length); | 2694 cset_region_length(), _young_list_fixed_length); |
3051 should_continue = false; | 2695 should_continue = false; |
3052 } | 2696 } |
3053 } | 2697 } |
3054 } | 2698 } |
3055 } while (should_continue); | 2699 } while (should_continue); |
3056 | 2700 |
3057 if (!adaptive_young_list_length() && | 2701 if (!adaptive_young_list_length() && |
3058 _collection_set_size < _young_list_fixed_length) { | 2702 cset_region_length() < _young_list_fixed_length) { |
3059 ergo_verbose2(ErgoCSetConstruction, | 2703 ergo_verbose2(ErgoCSetConstruction, |
3060 "request partially-young GCs end", | 2704 "request partially-young GCs end", |
3061 ergo_format_reason("CSet length lower than target") | 2705 ergo_format_reason("CSet length lower than target") |
3062 ergo_format_region("CSet") | 2706 ergo_format_region("CSet") |
3063 ergo_format_region("young target"), | 2707 ergo_format_region("young target"), |
3064 _collection_set_size, _young_list_fixed_length); | 2708 cset_region_length(), _young_list_fixed_length); |
3065 _should_revert_to_full_young_gcs = true; | 2709 _should_revert_to_full_young_gcs = true; |
3066 } | 2710 } |
3067 | |
3068 old_region_num = _collection_set_size - prev_collection_set_size; | |
3069 | 2711 |
3070 ergo_verbose2(ErgoCSetConstruction | ErgoHigh, | 2712 ergo_verbose2(ErgoCSetConstruction | ErgoHigh, |
3071 "add old regions to CSet", | 2713 "add old regions to CSet", |
3072 ergo_format_region("old") | 2714 ergo_format_region("old") |
3073 ergo_format_ms("predicted old region time"), | 2715 ergo_format_ms("predicted old region time"), |
3074 old_region_num, | 2716 old_cset_region_length(), |
3075 predicted_pause_time_ms - prev_predicted_pause_time_ms); | 2717 predicted_pause_time_ms - prev_predicted_pause_time_ms); |
3076 } | 2718 } |
3077 | 2719 |
3078 stop_incremental_cset_building(); | 2720 stop_incremental_cset_building(); |
3079 | 2721 |
3080 count_CS_bytes_used(); | 2722 count_CS_bytes_used(); |
3081 | |
3082 end_recording_regions(); | |
3083 | 2723 |
3084 ergo_verbose5(ErgoCSetConstruction, | 2724 ergo_verbose5(ErgoCSetConstruction, |
3085 "finish choosing CSet", | 2725 "finish choosing CSet", |
3086 ergo_format_region("eden") | 2726 ergo_format_region("eden") |
3087 ergo_format_region("survivors") | 2727 ergo_format_region("survivors") |
3088 ergo_format_region("old") | 2728 ergo_format_region("old") |
3089 ergo_format_ms("predicted pause time") | 2729 ergo_format_ms("predicted pause time") |
3090 ergo_format_ms("target pause time"), | 2730 ergo_format_ms("target pause time"), |
3091 eden_region_num, survivor_region_num, old_region_num, | 2731 eden_region_length, survivor_region_length, |
2732 old_cset_region_length(), | |
3092 predicted_pause_time_ms, target_pause_time_ms); | 2733 predicted_pause_time_ms, target_pause_time_ms); |
3093 | 2734 |
3094 double non_young_end_time_sec = os::elapsedTime(); | 2735 double non_young_end_time_sec = os::elapsedTime(); |
3095 _recorded_non_young_cset_choice_time_ms = | 2736 _recorded_non_young_cset_choice_time_ms = |
3096 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; | 2737 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; |