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

Mon, 03 Aug 2009 12:59:30 -0700

author
johnc
date
Mon, 03 Aug 2009 12:59:30 -0700
changeset 1324
15c5903cf9e1
parent 1280
df6caf649ff7
child 1325
6cb8e9df7174
permissions
-rw-r--r--

6865703: G1: Parallelize hot card cache cleanup
Summary: Have the GC worker threads clear the hot card cache in parallel by having each worker thread claim a chunk of the card cache and process the cards in that chunk. The size of the chunks that each thread will claim is determined at VM initialization from the size of the card cache and the number of worker threads.
Reviewed-by: jmasa, tonyp

ysr@777 1 /*
xdono@1014 2 * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
ysr@777 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
ysr@777 20 * CA 95054 USA or visit www.sun.com if you need additional information or
ysr@777 21 * have any questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
ysr@777 25 #include "incls/_precompiled.incl"
ysr@777 26 #include "incls/_g1CollectorPolicy.cpp.incl"
ysr@777 27
ysr@777 28 #define PREDICTIONS_VERBOSE 0
ysr@777 29
ysr@777 30 // <NEW PREDICTION>
ysr@777 31
ysr@777 32 // Different defaults for different number of GC threads
ysr@777 33 // They were chosen by running GCOld and SPECjbb on debris with different
ysr@777 34 // numbers of GC threads and choosing them based on the results
ysr@777 35
ysr@777 36 // all the same
ysr@777 37 static double rs_length_diff_defaults[] = {
ysr@777 38 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
ysr@777 39 };
ysr@777 40
ysr@777 41 static double cost_per_card_ms_defaults[] = {
ysr@777 42 0.01, 0.005, 0.005, 0.003, 0.003, 0.002, 0.002, 0.0015
ysr@777 43 };
ysr@777 44
ysr@777 45 static double cost_per_scan_only_region_ms_defaults[] = {
ysr@777 46 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
ysr@777 47 };
ysr@777 48
ysr@777 49 // all the same
ysr@777 50 static double fully_young_cards_per_entry_ratio_defaults[] = {
ysr@777 51 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
ysr@777 52 };
ysr@777 53
ysr@777 54 static double cost_per_entry_ms_defaults[] = {
ysr@777 55 0.015, 0.01, 0.01, 0.008, 0.008, 0.0055, 0.0055, 0.005
ysr@777 56 };
ysr@777 57
ysr@777 58 static double cost_per_byte_ms_defaults[] = {
ysr@777 59 0.00006, 0.00003, 0.00003, 0.000015, 0.000015, 0.00001, 0.00001, 0.000009
ysr@777 60 };
ysr@777 61
ysr@777 62 // these should be pretty consistent
ysr@777 63 static double constant_other_time_ms_defaults[] = {
ysr@777 64 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0
ysr@777 65 };
ysr@777 66
ysr@777 67
ysr@777 68 static double young_other_cost_per_region_ms_defaults[] = {
ysr@777 69 0.3, 0.2, 0.2, 0.15, 0.15, 0.12, 0.12, 0.1
ysr@777 70 };
ysr@777 71
ysr@777 72 static double non_young_other_cost_per_region_ms_defaults[] = {
ysr@777 73 1.0, 0.7, 0.7, 0.5, 0.5, 0.42, 0.42, 0.30
ysr@777 74 };
ysr@777 75
ysr@777 76 // </NEW PREDICTION>
ysr@777 77
ysr@777 78 G1CollectorPolicy::G1CollectorPolicy() :
ysr@777 79 _parallel_gc_threads((ParallelGCThreads > 0) ? ParallelGCThreads : 1),
ysr@777 80 _n_pauses(0),
ysr@777 81 _recent_CH_strong_roots_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 82 _recent_G1_strong_roots_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 83 _recent_evac_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 84 _recent_pause_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 85 _recent_rs_sizes(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 86 _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 87 _all_pause_times_ms(new NumberSeq()),
ysr@777 88 _stop_world_start(0.0),
ysr@777 89 _all_stop_world_times_ms(new NumberSeq()),
ysr@777 90 _all_yield_times_ms(new NumberSeq()),
ysr@777 91
ysr@777 92 _all_mod_union_times_ms(new NumberSeq()),
ysr@777 93
apetrusenko@1112 94 _summary(new Summary()),
apetrusenko@1112 95 _abandoned_summary(new AbandonedSummary()),
ysr@777 96
ysr@777 97 _cur_clear_ct_time_ms(0.0),
ysr@777 98
ysr@777 99 _region_num_young(0),
ysr@777 100 _region_num_tenured(0),
ysr@777 101 _prev_region_num_young(0),
ysr@777 102 _prev_region_num_tenured(0),
ysr@777 103
ysr@777 104 _aux_num(10),
ysr@777 105 _all_aux_times_ms(new NumberSeq[_aux_num]),
ysr@777 106 _cur_aux_start_times_ms(new double[_aux_num]),
ysr@777 107 _cur_aux_times_ms(new double[_aux_num]),
ysr@777 108 _cur_aux_times_set(new bool[_aux_num]),
ysr@777 109
ysr@777 110 _concurrent_mark_init_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 111 _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 112 _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 113
ysr@777 114 // <NEW PREDICTION>
ysr@777 115
ysr@777 116 _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 117 _prev_collection_pause_end_ms(0.0),
ysr@777 118 _pending_card_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 119 _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 120 _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 121 _cost_per_scan_only_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 122 _fully_young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 123 _partially_young_cards_per_entry_ratio_seq(
ysr@777 124 new TruncatedSeq(TruncatedSeqLength)),
ysr@777 125 _cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 126 _partially_young_cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 127 _cost_per_byte_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 128 _cost_per_byte_ms_during_cm_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 129 _cost_per_scan_only_region_ms_during_cm_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 130 _constant_other_time_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 131 _young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 132 _non_young_other_cost_per_region_ms_seq(
ysr@777 133 new TruncatedSeq(TruncatedSeqLength)),
ysr@777 134
ysr@777 135 _pending_cards_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 136 _scanned_cards_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 137 _rs_lengths_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 138
johnc@1186 139 _pause_time_target_ms((double) MaxGCPauseMillis),
ysr@777 140
ysr@777 141 // </NEW PREDICTION>
ysr@777 142
ysr@777 143 _in_young_gc_mode(false),
ysr@777 144 _full_young_gcs(true),
ysr@777 145 _full_young_pause_num(0),
ysr@777 146 _partial_young_pause_num(0),
ysr@777 147
ysr@777 148 _during_marking(false),
ysr@777 149 _in_marking_window(false),
ysr@777 150 _in_marking_window_im(false),
ysr@777 151
ysr@777 152 _known_garbage_ratio(0.0),
ysr@777 153 _known_garbage_bytes(0),
ysr@777 154
ysr@777 155 _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)),
ysr@777 156 _target_pause_time_ms(-1.0),
ysr@777 157
ysr@777 158 _recent_prev_end_times_for_all_gcs_sec(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 159
ysr@777 160 _recent_CS_bytes_used_before(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 161 _recent_CS_bytes_surviving(new TruncatedSeq(NumPrevPausesForHeuristics)),
ysr@777 162
ysr@777 163 _recent_avg_pause_time_ratio(0.0),
ysr@777 164 _num_markings(0),
ysr@777 165 _n_marks(0),
ysr@777 166 _n_pauses_at_mark_end(0),
ysr@777 167
ysr@777 168 _all_full_gc_times_ms(new NumberSeq()),
ysr@777 169
ysr@777 170 // G1PausesBtwnConcMark defaults to -1
ysr@777 171 // so the hack is to do the cast QQQ FIXME
ysr@777 172 _pauses_btwn_concurrent_mark((size_t)G1PausesBtwnConcMark),
ysr@777 173 _n_marks_since_last_pause(0),
ysr@777 174 _conc_mark_initiated(false),
ysr@777 175 _should_initiate_conc_mark(false),
ysr@777 176 _should_revert_to_full_young_gcs(false),
ysr@777 177 _last_full_young_gc(false),
ysr@777 178
ysr@777 179 _prev_collection_pause_used_at_end_bytes(0),
ysr@777 180
ysr@777 181 _collection_set(NULL),
ysr@777 182 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
ysr@777 183 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
ysr@777 184 #endif // _MSC_VER
ysr@777 185
ysr@777 186 _short_lived_surv_rate_group(new SurvRateGroup(this, "Short Lived",
ysr@777 187 G1YoungSurvRateNumRegionsSummary)),
ysr@777 188 _survivor_surv_rate_group(new SurvRateGroup(this, "Survivor",
apetrusenko@980 189 G1YoungSurvRateNumRegionsSummary)),
ysr@777 190 // add here any more surv rate groups
apetrusenko@980 191 _recorded_survivor_regions(0),
apetrusenko@980 192 _recorded_survivor_head(NULL),
apetrusenko@980 193 _recorded_survivor_tail(NULL),
apetrusenko@980 194 _survivors_age_table(true)
apetrusenko@980 195
ysr@777 196 {
ysr@777 197 _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
ysr@777 198 _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
ysr@777 199
ysr@777 200 _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads];
ysr@777 201 _par_last_mark_stack_scan_times_ms = new double[_parallel_gc_threads];
ysr@777 202 _par_last_scan_only_times_ms = new double[_parallel_gc_threads];
ysr@777 203 _par_last_scan_only_regions_scanned = new double[_parallel_gc_threads];
ysr@777 204
ysr@777 205 _par_last_update_rs_start_times_ms = new double[_parallel_gc_threads];
ysr@777 206 _par_last_update_rs_times_ms = new double[_parallel_gc_threads];
ysr@777 207 _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads];
ysr@777 208
ysr@777 209 _par_last_scan_rs_start_times_ms = new double[_parallel_gc_threads];
ysr@777 210 _par_last_scan_rs_times_ms = new double[_parallel_gc_threads];
ysr@777 211 _par_last_scan_new_refs_times_ms = new double[_parallel_gc_threads];
ysr@777 212
ysr@777 213 _par_last_obj_copy_times_ms = new double[_parallel_gc_threads];
ysr@777 214
ysr@777 215 _par_last_termination_times_ms = new double[_parallel_gc_threads];
ysr@777 216
ysr@777 217 // start conservatively
johnc@1186 218 _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis;
ysr@777 219
ysr@777 220 // <NEW PREDICTION>
ysr@777 221
ysr@777 222 int index;
ysr@777 223 if (ParallelGCThreads == 0)
ysr@777 224 index = 0;
ysr@777 225 else if (ParallelGCThreads > 8)
ysr@777 226 index = 7;
ysr@777 227 else
ysr@777 228 index = ParallelGCThreads - 1;
ysr@777 229
ysr@777 230 _pending_card_diff_seq->add(0.0);
ysr@777 231 _rs_length_diff_seq->add(rs_length_diff_defaults[index]);
ysr@777 232 _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]);
ysr@777 233 _cost_per_scan_only_region_ms_seq->add(
ysr@777 234 cost_per_scan_only_region_ms_defaults[index]);
ysr@777 235 _fully_young_cards_per_entry_ratio_seq->add(
ysr@777 236 fully_young_cards_per_entry_ratio_defaults[index]);
ysr@777 237 _cost_per_entry_ms_seq->add(cost_per_entry_ms_defaults[index]);
ysr@777 238 _cost_per_byte_ms_seq->add(cost_per_byte_ms_defaults[index]);
ysr@777 239 _constant_other_time_ms_seq->add(constant_other_time_ms_defaults[index]);
ysr@777 240 _young_other_cost_per_region_ms_seq->add(
ysr@777 241 young_other_cost_per_region_ms_defaults[index]);
ysr@777 242 _non_young_other_cost_per_region_ms_seq->add(
ysr@777 243 non_young_other_cost_per_region_ms_defaults[index]);
ysr@777 244
ysr@777 245 // </NEW PREDICTION>
ysr@777 246
johnc@1186 247 double time_slice = (double) GCPauseIntervalMillis / 1000.0;
johnc@1186 248 double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
ysr@777 249 guarantee(max_gc_time < time_slice,
ysr@777 250 "Max GC time should not be greater than the time slice");
ysr@777 251 _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
johnc@1186 252 _sigma = (double) G1ConfidencePercent / 100.0;
ysr@777 253
ysr@777 254 // start conservatively (around 50ms is about right)
ysr@777 255 _concurrent_mark_init_times_ms->add(0.05);
ysr@777 256 _concurrent_mark_remark_times_ms->add(0.05);
ysr@777 257 _concurrent_mark_cleanup_times_ms->add(0.20);
ysr@777 258 _tenuring_threshold = MaxTenuringThreshold;
ysr@777 259
johnc@1186 260 if (G1UseSurvivorSpaces) {
apetrusenko@980 261 // if G1FixedSurvivorSpaceSize is 0 which means the size is not
apetrusenko@980 262 // fixed, then _max_survivor_regions will be calculated at
apetrusenko@982 263 // calculate_young_list_target_config during initialization
apetrusenko@980 264 _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
apetrusenko@980 265 } else {
apetrusenko@980 266 _max_survivor_regions = 0;
apetrusenko@980 267 }
apetrusenko@980 268
ysr@777 269 initialize_all();
ysr@777 270 }
ysr@777 271
ysr@777 272 // Increment "i", mod "len"
ysr@777 273 static void inc_mod(int& i, int len) {
ysr@777 274 i++; if (i == len) i = 0;
ysr@777 275 }
ysr@777 276
ysr@777 277 void G1CollectorPolicy::initialize_flags() {
ysr@777 278 set_min_alignment(HeapRegion::GrainBytes);
ysr@777 279 set_max_alignment(GenRemSet::max_alignment_constraint(rem_set_name()));
apetrusenko@982 280 if (SurvivorRatio < 1) {
apetrusenko@982 281 vm_exit_during_initialization("Invalid survivor ratio specified");
apetrusenko@982 282 }
ysr@777 283 CollectorPolicy::initialize_flags();
ysr@777 284 }
ysr@777 285
ysr@777 286 void G1CollectorPolicy::init() {
ysr@777 287 // Set aside an initial future to_space.
ysr@777 288 _g1 = G1CollectedHeap::heap();
ysr@777 289 size_t regions = Universe::heap()->capacity() / HeapRegion::GrainBytes;
ysr@777 290
ysr@777 291 assert(Heap_lock->owned_by_self(), "Locking discipline.");
ysr@777 292
ysr@777 293 if (G1SteadyStateUsed < 50) {
ysr@777 294 vm_exit_during_initialization("G1SteadyStateUsed must be at least 50%.");
ysr@777 295 }
ysr@777 296
apetrusenko@980 297 initialize_gc_policy_counters();
apetrusenko@980 298
ysr@777 299 if (G1Gen) {
ysr@777 300 _in_young_gc_mode = true;
ysr@777 301
ysr@777 302 if (G1YoungGenSize == 0) {
ysr@777 303 set_adaptive_young_list_length(true);
ysr@777 304 _young_list_fixed_length = 0;
ysr@777 305 } else {
ysr@777 306 set_adaptive_young_list_length(false);
ysr@777 307 _young_list_fixed_length = (G1YoungGenSize / HeapRegion::GrainBytes);
ysr@777 308 }
ysr@777 309 _free_regions_at_end_of_collection = _g1->free_regions();
ysr@777 310 _scan_only_regions_at_end_of_collection = 0;
ysr@777 311 calculate_young_list_min_length();
ysr@777 312 guarantee( _young_list_min_length == 0, "invariant, not enough info" );
ysr@777 313 calculate_young_list_target_config();
ysr@777 314 } else {
ysr@777 315 _young_list_fixed_length = 0;
ysr@777 316 _in_young_gc_mode = false;
ysr@777 317 }
ysr@777 318 }
ysr@777 319
apetrusenko@980 320 // Create the jstat counters for the policy.
apetrusenko@980 321 void G1CollectorPolicy::initialize_gc_policy_counters()
apetrusenko@980 322 {
apetrusenko@980 323 _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 2 + G1Gen);
apetrusenko@980 324 }
apetrusenko@980 325
ysr@777 326 void G1CollectorPolicy::calculate_young_list_min_length() {
ysr@777 327 _young_list_min_length = 0;
ysr@777 328
ysr@777 329 if (!adaptive_young_list_length())
ysr@777 330 return;
ysr@777 331
ysr@777 332 if (_alloc_rate_ms_seq->num() > 3) {
ysr@777 333 double now_sec = os::elapsedTime();
ysr@777 334 double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
ysr@777 335 double alloc_rate_ms = predict_alloc_rate_ms();
ysr@777 336 int min_regions = (int) ceil(alloc_rate_ms * when_ms);
ysr@777 337 int current_region_num = (int) _g1->young_list_length();
ysr@777 338 _young_list_min_length = min_regions + current_region_num;
ysr@777 339 }
ysr@777 340 }
ysr@777 341
ysr@777 342 void G1CollectorPolicy::calculate_young_list_target_config() {
ysr@777 343 if (adaptive_young_list_length()) {
ysr@777 344 size_t rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq);
ysr@777 345 calculate_young_list_target_config(rs_lengths);
ysr@777 346 } else {
ysr@777 347 if (full_young_gcs())
ysr@777 348 _young_list_target_length = _young_list_fixed_length;
ysr@777 349 else
ysr@777 350 _young_list_target_length = _young_list_fixed_length / 2;
ysr@777 351 _young_list_target_length = MAX2(_young_list_target_length, (size_t)1);
ysr@777 352 size_t so_length = calculate_optimal_so_length(_young_list_target_length);
ysr@777 353 guarantee( so_length < _young_list_target_length, "invariant" );
ysr@777 354 _young_list_so_prefix_length = so_length;
ysr@777 355 }
apetrusenko@980 356 calculate_survivors_policy();
ysr@777 357 }
ysr@777 358
ysr@777 359 // This method calculate the optimal scan-only set for a fixed young
ysr@777 360 // gen size. I couldn't work out how to reuse the more elaborate one,
ysr@777 361 // i.e. calculate_young_list_target_config(rs_length), as the loops are
ysr@777 362 // fundamentally different (the other one finds a config for different
ysr@777 363 // S-O lengths, whereas here we need to do the opposite).
ysr@777 364 size_t G1CollectorPolicy::calculate_optimal_so_length(
ysr@777 365 size_t young_list_length) {
ysr@777 366 if (!G1UseScanOnlyPrefix)
ysr@777 367 return 0;
ysr@777 368
ysr@777 369 if (_all_pause_times_ms->num() < 3) {
ysr@777 370 // we won't use a scan-only set at the beginning to allow the rest
ysr@777 371 // of the predictors to warm up
ysr@777 372 return 0;
ysr@777 373 }
ysr@777 374
ysr@777 375 if (_cost_per_scan_only_region_ms_seq->num() < 3) {
ysr@777 376 // then, we'll only set the S-O set to 1 for a little bit of time,
ysr@777 377 // to get enough information on the scanning cost
ysr@777 378 return 1;
ysr@777 379 }
ysr@777 380
ysr@777 381 size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq);
ysr@777 382 size_t rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq);
ysr@777 383 size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff();
ysr@777 384 size_t scanned_cards;
ysr@777 385 if (full_young_gcs())
ysr@777 386 scanned_cards = predict_young_card_num(adj_rs_lengths);
ysr@777 387 else
ysr@777 388 scanned_cards = predict_non_young_card_num(adj_rs_lengths);
ysr@777 389 double base_time_ms = predict_base_elapsed_time_ms(pending_cards,
ysr@777 390 scanned_cards);
ysr@777 391
ysr@777 392 size_t so_length = 0;
ysr@777 393 double max_gc_eff = 0.0;
ysr@777 394 for (size_t i = 0; i < young_list_length; ++i) {
ysr@777 395 double gc_eff = 0.0;
ysr@777 396 double pause_time_ms = 0.0;
ysr@777 397 predict_gc_eff(young_list_length, i, base_time_ms,
ysr@777 398 &gc_eff, &pause_time_ms);
ysr@777 399 if (gc_eff > max_gc_eff) {
ysr@777 400 max_gc_eff = gc_eff;
ysr@777 401 so_length = i;
ysr@777 402 }
ysr@777 403 }
ysr@777 404
ysr@777 405 // set it to 95% of the optimal to make sure we sample the "area"
ysr@777 406 // around the optimal length to get up-to-date survival rate data
ysr@777 407 return so_length * 950 / 1000;
ysr@777 408 }
ysr@777 409
ysr@777 410 // This is a really cool piece of code! It finds the best
ysr@777 411 // target configuration (young length / scan-only prefix length) so
ysr@777 412 // that GC efficiency is maximized and that we also meet a pause
ysr@777 413 // time. It's a triple nested loop. These loops are explained below
ysr@777 414 // from the inside-out :-)
ysr@777 415 //
ysr@777 416 // (a) The innermost loop will try to find the optimal young length
ysr@777 417 // for a fixed S-O length. It uses a binary search to speed up the
ysr@777 418 // process. We assume that, for a fixed S-O length, as we add more
ysr@777 419 // young regions to the CSet, the GC efficiency will only go up (I'll
ysr@777 420 // skip the proof). So, using a binary search to optimize this process
ysr@777 421 // makes perfect sense.
ysr@777 422 //
ysr@777 423 // (b) The middle loop will fix the S-O length before calling the
ysr@777 424 // innermost one. It will vary it between two parameters, increasing
ysr@777 425 // it by a given increment.
ysr@777 426 //
ysr@777 427 // (c) The outermost loop will call the middle loop three times.
ysr@777 428 // (1) The first time it will explore all possible S-O length values
ysr@777 429 // from 0 to as large as it can get, using a coarse increment (to
ysr@777 430 // quickly "home in" to where the optimal seems to be).
ysr@777 431 // (2) The second time it will explore the values around the optimal
ysr@777 432 // that was found by the first iteration using a fine increment.
ysr@777 433 // (3) Once the optimal config has been determined by the second
ysr@777 434 // iteration, we'll redo the calculation, but setting the S-O length
ysr@777 435 // to 95% of the optimal to make sure we sample the "area"
ysr@777 436 // around the optimal length to get up-to-date survival rate data
ysr@777 437 //
ysr@777 438 // Termination conditions for the iterations are several: the pause
ysr@777 439 // time is over the limit, we do not have enough to-space, etc.
ysr@777 440
ysr@777 441 void G1CollectorPolicy::calculate_young_list_target_config(size_t rs_lengths) {
ysr@777 442 guarantee( adaptive_young_list_length(), "pre-condition" );
ysr@777 443
ysr@777 444 double start_time_sec = os::elapsedTime();
johnc@1186 445 size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1MinReservePercent);
ysr@777 446 min_reserve_perc = MIN2((size_t) 50, min_reserve_perc);
ysr@777 447 size_t reserve_regions =
ysr@777 448 (size_t) ((double) min_reserve_perc * (double) _g1->n_regions() / 100.0);
ysr@777 449
ysr@777 450 if (full_young_gcs() && _free_regions_at_end_of_collection > 0) {
ysr@777 451 // we are in fully-young mode and there are free regions in the heap
ysr@777 452
apetrusenko@980 453 double survivor_regions_evac_time =
apetrusenko@980 454 predict_survivor_regions_evac_time();
apetrusenko@980 455
ysr@777 456 size_t min_so_length = 0;
ysr@777 457 size_t max_so_length = 0;
ysr@777 458
ysr@777 459 if (G1UseScanOnlyPrefix) {
ysr@777 460 if (_all_pause_times_ms->num() < 3) {
ysr@777 461 // we won't use a scan-only set at the beginning to allow the rest
ysr@777 462 // of the predictors to warm up
ysr@777 463 min_so_length = 0;
ysr@777 464 max_so_length = 0;
ysr@777 465 } else if (_cost_per_scan_only_region_ms_seq->num() < 3) {
ysr@777 466 // then, we'll only set the S-O set to 1 for a little bit of time,
ysr@777 467 // to get enough information on the scanning cost
ysr@777 468 min_so_length = 1;
ysr@777 469 max_so_length = 1;
ysr@777 470 } else if (_in_marking_window || _last_full_young_gc) {
ysr@777 471 // no S-O prefix during a marking phase either, as at the end
ysr@777 472 // of the marking phase we'll have to use a very small young
ysr@777 473 // length target to fill up the rest of the CSet with
ysr@777 474 // non-young regions and, if we have lots of scan-only regions
ysr@777 475 // left-over, we will not be able to add any more non-young
ysr@777 476 // regions.
ysr@777 477 min_so_length = 0;
ysr@777 478 max_so_length = 0;
ysr@777 479 } else {
ysr@777 480 // this is the common case; we'll never reach the maximum, we
ysr@777 481 // one of the end conditions will fire well before that
ysr@777 482 // (hopefully!)
ysr@777 483 min_so_length = 0;
ysr@777 484 max_so_length = _free_regions_at_end_of_collection - 1;
ysr@777 485 }
ysr@777 486 } else {
ysr@777 487 // no S-O prefix, as the switch is not set, but we still need to
ysr@777 488 // do one iteration to calculate the best young target that
ysr@777 489 // meets the pause time; this way we reuse the same code instead
ysr@777 490 // of replicating it
ysr@777 491 min_so_length = 0;
ysr@777 492 max_so_length = 0;
ysr@777 493 }
ysr@777 494
ysr@777 495 double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
ysr@777 496 size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq);
ysr@777 497 size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff();
ysr@777 498 size_t scanned_cards;
ysr@777 499 if (full_young_gcs())
ysr@777 500 scanned_cards = predict_young_card_num(adj_rs_lengths);
ysr@777 501 else
ysr@777 502 scanned_cards = predict_non_young_card_num(adj_rs_lengths);
ysr@777 503 // calculate this once, so that we don't have to recalculate it in
ysr@777 504 // the innermost loop
apetrusenko@980 505 double base_time_ms = predict_base_elapsed_time_ms(pending_cards, scanned_cards)
apetrusenko@980 506 + survivor_regions_evac_time;
ysr@777 507 // the result
ysr@777 508 size_t final_young_length = 0;
ysr@777 509 size_t final_so_length = 0;
ysr@777 510 double final_gc_eff = 0.0;
ysr@777 511 // we'll also keep track of how many times we go into the inner loop
ysr@777 512 // this is for profiling reasons
ysr@777 513 size_t calculations = 0;
ysr@777 514
ysr@777 515 // this determines which of the three iterations the outer loop is in
ysr@777 516 typedef enum {
ysr@777 517 pass_type_coarse,
ysr@777 518 pass_type_fine,
ysr@777 519 pass_type_final
ysr@777 520 } pass_type_t;
ysr@777 521
ysr@777 522 // range of the outer loop's iteration
ysr@777 523 size_t from_so_length = min_so_length;
ysr@777 524 size_t to_so_length = max_so_length;
ysr@777 525 guarantee( from_so_length <= to_so_length, "invariant" );
ysr@777 526
ysr@777 527 // this will keep the S-O length that's found by the second
ysr@777 528 // iteration of the outer loop; we'll keep it just in case the third
ysr@777 529 // iteration fails to find something
ysr@777 530 size_t fine_so_length = 0;
ysr@777 531
ysr@777 532 // the increment step for the coarse (first) iteration
ysr@777 533 size_t so_coarse_increments = 5;
ysr@777 534
ysr@777 535 // the common case, we'll start with the coarse iteration
ysr@777 536 pass_type_t pass = pass_type_coarse;
ysr@777 537 size_t so_length_incr = so_coarse_increments;
ysr@777 538
ysr@777 539 if (from_so_length == to_so_length) {
ysr@777 540 // not point in doing the coarse iteration, we'll go directly into
ysr@777 541 // the fine one (we essentially trying to find the optimal young
ysr@777 542 // length for a fixed S-O length).
ysr@777 543 so_length_incr = 1;
ysr@777 544 pass = pass_type_final;
ysr@777 545 } else if (to_so_length - from_so_length < 3 * so_coarse_increments) {
ysr@777 546 // again, the range is too short so no point in foind the coarse
ysr@777 547 // iteration either
ysr@777 548 so_length_incr = 1;
ysr@777 549 pass = pass_type_fine;
ysr@777 550 }
ysr@777 551
ysr@777 552 bool done = false;
ysr@777 553 // this is the outermost loop
ysr@777 554 while (!done) {
apetrusenko@980 555 #ifdef TRACE_CALC_YOUNG_CONFIG
ysr@777 556 // leave this in for debugging, just in case
ysr@777 557 gclog_or_tty->print_cr("searching between " SIZE_FORMAT " and " SIZE_FORMAT
ysr@777 558 ", incr " SIZE_FORMAT ", pass %s",
ysr@777 559 from_so_length, to_so_length, so_length_incr,
ysr@777 560 (pass == pass_type_coarse) ? "coarse" :
ysr@777 561 (pass == pass_type_fine) ? "fine" : "final");
apetrusenko@980 562 #endif // TRACE_CALC_YOUNG_CONFIG
ysr@777 563
ysr@777 564 size_t so_length = from_so_length;
ysr@777 565 size_t init_free_regions =
ysr@777 566 MAX2((size_t)0,
ysr@777 567 _free_regions_at_end_of_collection +
ysr@777 568 _scan_only_regions_at_end_of_collection - reserve_regions);
ysr@777 569
ysr@777 570 // this determines whether a configuration was found
ysr@777 571 bool gc_eff_set = false;
ysr@777 572 // this is the middle loop
ysr@777 573 while (so_length <= to_so_length) {
ysr@777 574 // base time, which excludes region-related time; again we
ysr@777 575 // calculate it once to avoid recalculating it in the
ysr@777 576 // innermost loop
ysr@777 577 double base_time_with_so_ms =
ysr@777 578 base_time_ms + predict_scan_only_time_ms(so_length);
ysr@777 579 // it's already over the pause target, go around
ysr@777 580 if (base_time_with_so_ms > target_pause_time_ms)
ysr@777 581 break;
ysr@777 582
ysr@777 583 size_t starting_young_length = so_length+1;
ysr@777 584
ysr@777 585 // we make sure that the short young length that makes sense
ysr@777 586 // (one more than the S-O length) is feasible
ysr@777 587 size_t min_young_length = starting_young_length;
ysr@777 588 double min_gc_eff;
ysr@777 589 bool min_ok;
ysr@777 590 ++calculations;
ysr@777 591 min_ok = predict_gc_eff(min_young_length, so_length,
ysr@777 592 base_time_with_so_ms,
ysr@777 593 init_free_regions, target_pause_time_ms,
ysr@777 594 &min_gc_eff);
ysr@777 595
ysr@777 596 if (min_ok) {
ysr@777 597 // the shortest young length is indeed feasible; we'll know
ysr@777 598 // set up the max young length and we'll do a binary search
ysr@777 599 // between min_young_length and max_young_length
ysr@777 600 size_t max_young_length = _free_regions_at_end_of_collection - 1;
ysr@777 601 double max_gc_eff = 0.0;
ysr@777 602 bool max_ok = false;
ysr@777 603
ysr@777 604 // the innermost loop! (finally!)
ysr@777 605 while (max_young_length > min_young_length) {
ysr@777 606 // we'll make sure that min_young_length is always at a
ysr@777 607 // feasible config
ysr@777 608 guarantee( min_ok, "invariant" );
ysr@777 609
ysr@777 610 ++calculations;
ysr@777 611 max_ok = predict_gc_eff(max_young_length, so_length,
ysr@777 612 base_time_with_so_ms,
ysr@777 613 init_free_regions, target_pause_time_ms,
ysr@777 614 &max_gc_eff);
ysr@777 615
ysr@777 616 size_t diff = (max_young_length - min_young_length) / 2;
ysr@777 617 if (max_ok) {
ysr@777 618 min_young_length = max_young_length;
ysr@777 619 min_gc_eff = max_gc_eff;
ysr@777 620 min_ok = true;
ysr@777 621 }
ysr@777 622 max_young_length = min_young_length + diff;
ysr@777 623 }
ysr@777 624
ysr@777 625 // the innermost loop found a config
ysr@777 626 guarantee( min_ok, "invariant" );
ysr@777 627 if (min_gc_eff > final_gc_eff) {
ysr@777 628 // it's the best config so far, so we'll keep it
ysr@777 629 final_gc_eff = min_gc_eff;
ysr@777 630 final_young_length = min_young_length;
ysr@777 631 final_so_length = so_length;
ysr@777 632 gc_eff_set = true;
ysr@777 633 }
ysr@777 634 }
ysr@777 635
ysr@777 636 // incremental the fixed S-O length and go around
ysr@777 637 so_length += so_length_incr;
ysr@777 638 }
ysr@777 639
ysr@777 640 // this is the end of the outermost loop and we need to decide
ysr@777 641 // what to do during the next iteration
ysr@777 642 if (pass == pass_type_coarse) {
ysr@777 643 // we just did the coarse pass (first iteration)
ysr@777 644
ysr@777 645 if (!gc_eff_set)
ysr@777 646 // we didn't find a feasible config so we'll just bail out; of
ysr@777 647 // course, it might be the case that we missed it; but I'd say
ysr@777 648 // it's a bit unlikely
ysr@777 649 done = true;
ysr@777 650 else {
ysr@777 651 // We did find a feasible config with optimal GC eff during
ysr@777 652 // the first pass. So the second pass we'll only consider the
ysr@777 653 // S-O lengths around that config with a fine increment.
ysr@777 654
ysr@777 655 guarantee( so_length_incr == so_coarse_increments, "invariant" );
ysr@777 656 guarantee( final_so_length >= min_so_length, "invariant" );
ysr@777 657
apetrusenko@980 658 #ifdef TRACE_CALC_YOUNG_CONFIG
ysr@777 659 // leave this in for debugging, just in case
ysr@777 660 gclog_or_tty->print_cr(" coarse pass: SO length " SIZE_FORMAT,
ysr@777 661 final_so_length);
apetrusenko@980 662 #endif // TRACE_CALC_YOUNG_CONFIG
ysr@777 663
ysr@777 664 from_so_length =
ysr@777 665 (final_so_length - min_so_length > so_coarse_increments) ?
ysr@777 666 final_so_length - so_coarse_increments + 1 : min_so_length;
ysr@777 667 to_so_length =
ysr@777 668 (max_so_length - final_so_length > so_coarse_increments) ?
ysr@777 669 final_so_length + so_coarse_increments - 1 : max_so_length;
ysr@777 670
ysr@777 671 pass = pass_type_fine;
ysr@777 672 so_length_incr = 1;
ysr@777 673 }
ysr@777 674 } else if (pass == pass_type_fine) {
ysr@777 675 // we just finished the second pass
ysr@777 676
ysr@777 677 if (!gc_eff_set) {
ysr@777 678 // we didn't find a feasible config (yes, it's possible;
ysr@777 679 // notice that, sometimes, we go directly into the fine
ysr@777 680 // iteration and skip the coarse one) so we bail out
ysr@777 681 done = true;
ysr@777 682 } else {
ysr@777 683 // We did find a feasible config with optimal GC eff
ysr@777 684 guarantee( so_length_incr == 1, "invariant" );
ysr@777 685
ysr@777 686 if (final_so_length == 0) {
ysr@777 687 // The config is of an empty S-O set, so we'll just bail out
ysr@777 688 done = true;
ysr@777 689 } else {
ysr@777 690 // we'll go around once more, setting the S-O length to 95%
ysr@777 691 // of the optimal
ysr@777 692 size_t new_so_length = 950 * final_so_length / 1000;
ysr@777 693
apetrusenko@980 694 #ifdef TRACE_CALC_YOUNG_CONFIG
ysr@777 695 // leave this in for debugging, just in case
ysr@777 696 gclog_or_tty->print_cr(" fine pass: SO length " SIZE_FORMAT
ysr@777 697 ", setting it to " SIZE_FORMAT,
ysr@777 698 final_so_length, new_so_length);
apetrusenko@980 699 #endif // TRACE_CALC_YOUNG_CONFIG
ysr@777 700
ysr@777 701 from_so_length = new_so_length;
ysr@777 702 to_so_length = new_so_length;
ysr@777 703 fine_so_length = final_so_length;
ysr@777 704
ysr@777 705 pass = pass_type_final;
ysr@777 706 }
ysr@777 707 }
ysr@777 708 } else if (pass == pass_type_final) {
ysr@777 709 // we just finished the final (third) pass
ysr@777 710
ysr@777 711 if (!gc_eff_set)
ysr@777 712 // we didn't find a feasible config, so we'll just use the one
ysr@777 713 // we found during the second pass, which we saved
ysr@777 714 final_so_length = fine_so_length;
ysr@777 715
ysr@777 716 // and we're done!
ysr@777 717 done = true;
ysr@777 718 } else {
ysr@777 719 guarantee( false, "should never reach here" );
ysr@777 720 }
ysr@777 721
ysr@777 722 // we now go around the outermost loop
ysr@777 723 }
ysr@777 724
ysr@777 725 // we should have at least one region in the target young length
apetrusenko@980 726 _young_list_target_length =
apetrusenko@980 727 MAX2((size_t) 1, final_young_length + _recorded_survivor_regions);
ysr@777 728 if (final_so_length >= final_young_length)
ysr@777 729 // and we need to ensure that the S-O length is not greater than
ysr@777 730 // the target young length (this is being a bit careful)
ysr@777 731 final_so_length = 0;
ysr@777 732 _young_list_so_prefix_length = final_so_length;
ysr@777 733 guarantee( !_in_marking_window || !_last_full_young_gc ||
ysr@777 734 _young_list_so_prefix_length == 0, "invariant" );
ysr@777 735
ysr@777 736 // let's keep an eye of how long we spend on this calculation
ysr@777 737 // right now, I assume that we'll print it when we need it; we
ysr@777 738 // should really adde it to the breakdown of a pause
ysr@777 739 double end_time_sec = os::elapsedTime();
ysr@777 740 double elapsed_time_ms = (end_time_sec - start_time_sec) * 1000.0;
ysr@777 741
apetrusenko@980 742 #ifdef TRACE_CALC_YOUNG_CONFIG
ysr@777 743 // leave this in for debugging, just in case
ysr@777 744 gclog_or_tty->print_cr("target = %1.1lf ms, young = " SIZE_FORMAT
ysr@777 745 ", SO = " SIZE_FORMAT ", "
ysr@777 746 "elapsed %1.2lf ms, calcs: " SIZE_FORMAT " (%s%s) "
ysr@777 747 SIZE_FORMAT SIZE_FORMAT,
ysr@777 748 target_pause_time_ms,
ysr@777 749 _young_list_target_length - _young_list_so_prefix_length,
ysr@777 750 _young_list_so_prefix_length,
ysr@777 751 elapsed_time_ms,
ysr@777 752 calculations,
ysr@777 753 full_young_gcs() ? "full" : "partial",
ysr@777 754 should_initiate_conc_mark() ? " i-m" : "",
apetrusenko@980 755 _in_marking_window,
apetrusenko@980 756 _in_marking_window_im);
apetrusenko@980 757 #endif // TRACE_CALC_YOUNG_CONFIG
ysr@777 758
ysr@777 759 if (_young_list_target_length < _young_list_min_length) {
ysr@777 760 // bummer; this means that, if we do a pause when the optimal
ysr@777 761 // config dictates, we'll violate the pause spacing target (the
ysr@777 762 // min length was calculate based on the application's current
ysr@777 763 // alloc rate);
ysr@777 764
ysr@777 765 // so, we have to bite the bullet, and allocate the minimum
ysr@777 766 // number. We'll violate our target, but we just can't meet it.
ysr@777 767
ysr@777 768 size_t so_length = 0;
ysr@777 769 // a note further up explains why we do not want an S-O length
ysr@777 770 // during marking
ysr@777 771 if (!_in_marking_window && !_last_full_young_gc)
ysr@777 772 // but we can still try to see whether we can find an optimal
ysr@777 773 // S-O length
ysr@777 774 so_length = calculate_optimal_so_length(_young_list_min_length);
ysr@777 775
apetrusenko@980 776 #ifdef TRACE_CALC_YOUNG_CONFIG
ysr@777 777 // leave this in for debugging, just in case
ysr@777 778 gclog_or_tty->print_cr("adjusted target length from "
ysr@777 779 SIZE_FORMAT " to " SIZE_FORMAT
ysr@777 780 ", SO " SIZE_FORMAT,
ysr@777 781 _young_list_target_length, _young_list_min_length,
ysr@777 782 so_length);
apetrusenko@980 783 #endif // TRACE_CALC_YOUNG_CONFIG
ysr@777 784
ysr@777 785 _young_list_target_length =
ysr@777 786 MAX2(_young_list_min_length, (size_t)1);
ysr@777 787 _young_list_so_prefix_length = so_length;
ysr@777 788 }
ysr@777 789 } else {
ysr@777 790 // we are in a partially-young mode or we've run out of regions (due
ysr@777 791 // to evacuation failure)
ysr@777 792
apetrusenko@980 793 #ifdef TRACE_CALC_YOUNG_CONFIG
ysr@777 794 // leave this in for debugging, just in case
ysr@777 795 gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT
ysr@777 796 ", SO " SIZE_FORMAT,
ysr@777 797 _young_list_min_length, 0);
apetrusenko@980 798 #endif // TRACE_CALC_YOUNG_CONFIG
ysr@777 799
ysr@777 800 // we'll do the pause as soon as possible and with no S-O prefix
ysr@777 801 // (see above for the reasons behind the latter)
ysr@777 802 _young_list_target_length =
ysr@777 803 MAX2(_young_list_min_length, (size_t) 1);
ysr@777 804 _young_list_so_prefix_length = 0;
ysr@777 805 }
ysr@777 806
ysr@777 807 _rs_lengths_prediction = rs_lengths;
ysr@777 808 }
ysr@777 809
ysr@777 810 // This is used by: calculate_optimal_so_length(length). It returns
ysr@777 811 // the GC eff and predicted pause time for a particular config
ysr@777 812 void
ysr@777 813 G1CollectorPolicy::predict_gc_eff(size_t young_length,
ysr@777 814 size_t so_length,
ysr@777 815 double base_time_ms,
ysr@777 816 double* ret_gc_eff,
ysr@777 817 double* ret_pause_time_ms) {
ysr@777 818 double so_time_ms = predict_scan_only_time_ms(so_length);
ysr@777 819 double accum_surv_rate_adj = 0.0;
ysr@777 820 if (so_length > 0)
ysr@777 821 accum_surv_rate_adj = accum_yg_surv_rate_pred((int)(so_length - 1));
ysr@777 822 double accum_surv_rate =
ysr@777 823 accum_yg_surv_rate_pred((int)(young_length - 1)) - accum_surv_rate_adj;
ysr@777 824 size_t bytes_to_copy =
ysr@777 825 (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes);
ysr@777 826 double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy);
ysr@777 827 double young_other_time_ms =
ysr@777 828 predict_young_other_time_ms(young_length - so_length);
ysr@777 829 double pause_time_ms =
ysr@777 830 base_time_ms + so_time_ms + copy_time_ms + young_other_time_ms;
ysr@777 831 size_t reclaimed_bytes =
ysr@777 832 (young_length - so_length) * HeapRegion::GrainBytes - bytes_to_copy;
ysr@777 833 double gc_eff = (double) reclaimed_bytes / pause_time_ms;
ysr@777 834
ysr@777 835 *ret_gc_eff = gc_eff;
ysr@777 836 *ret_pause_time_ms = pause_time_ms;
ysr@777 837 }
ysr@777 838
ysr@777 839 // This is used by: calculate_young_list_target_config(rs_length). It
ysr@777 840 // returns the GC eff of a particular config. It returns false if that
ysr@777 841 // config violates any of the end conditions of the search in the
ysr@777 842 // calling method, or true upon success. The end conditions were put
ysr@777 843 // here since it's called twice and it was best not to replicate them
ysr@777 844 // in the caller. Also, passing the parameteres avoids having to
ysr@777 845 // recalculate them in the innermost loop.
ysr@777 846 bool
ysr@777 847 G1CollectorPolicy::predict_gc_eff(size_t young_length,
ysr@777 848 size_t so_length,
ysr@777 849 double base_time_with_so_ms,
ysr@777 850 size_t init_free_regions,
ysr@777 851 double target_pause_time_ms,
ysr@777 852 double* ret_gc_eff) {
ysr@777 853 *ret_gc_eff = 0.0;
ysr@777 854
ysr@777 855 if (young_length >= init_free_regions)
ysr@777 856 // end condition 1: not enough space for the young regions
ysr@777 857 return false;
ysr@777 858
ysr@777 859 double accum_surv_rate_adj = 0.0;
ysr@777 860 if (so_length > 0)
ysr@777 861 accum_surv_rate_adj = accum_yg_surv_rate_pred((int)(so_length - 1));
ysr@777 862 double accum_surv_rate =
ysr@777 863 accum_yg_surv_rate_pred((int)(young_length - 1)) - accum_surv_rate_adj;
ysr@777 864 size_t bytes_to_copy =
ysr@777 865 (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes);
ysr@777 866 double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy);
ysr@777 867 double young_other_time_ms =
ysr@777 868 predict_young_other_time_ms(young_length - so_length);
ysr@777 869 double pause_time_ms =
ysr@777 870 base_time_with_so_ms + copy_time_ms + young_other_time_ms;
ysr@777 871
ysr@777 872 if (pause_time_ms > target_pause_time_ms)
ysr@777 873 // end condition 2: over the target pause time
ysr@777 874 return false;
ysr@777 875
ysr@777 876 size_t reclaimed_bytes =
ysr@777 877 (young_length - so_length) * HeapRegion::GrainBytes - bytes_to_copy;
ysr@777 878 size_t free_bytes =
ysr@777 879 (init_free_regions - young_length) * HeapRegion::GrainBytes;
ysr@777 880
ysr@777 881 if ((2.0 + sigma()) * (double) bytes_to_copy > (double) free_bytes)
ysr@777 882 // end condition 3: out of to-space (conservatively)
ysr@777 883 return false;
ysr@777 884
ysr@777 885 // success!
ysr@777 886 double gc_eff = (double) reclaimed_bytes / pause_time_ms;
ysr@777 887 *ret_gc_eff = gc_eff;
ysr@777 888
ysr@777 889 return true;
ysr@777 890 }
ysr@777 891
apetrusenko@980 892 double G1CollectorPolicy::predict_survivor_regions_evac_time() {
apetrusenko@980 893 double survivor_regions_evac_time = 0.0;
apetrusenko@980 894 for (HeapRegion * r = _recorded_survivor_head;
apetrusenko@980 895 r != NULL && r != _recorded_survivor_tail->get_next_young_region();
apetrusenko@980 896 r = r->get_next_young_region()) {
apetrusenko@980 897 survivor_regions_evac_time += predict_region_elapsed_time_ms(r, true);
apetrusenko@980 898 }
apetrusenko@980 899 return survivor_regions_evac_time;
apetrusenko@980 900 }
apetrusenko@980 901
ysr@777 902 void G1CollectorPolicy::check_prediction_validity() {
ysr@777 903 guarantee( adaptive_young_list_length(), "should not call this otherwise" );
ysr@777 904
ysr@777 905 size_t rs_lengths = _g1->young_list_sampled_rs_lengths();
ysr@777 906 if (rs_lengths > _rs_lengths_prediction) {
ysr@777 907 // add 10% to avoid having to recalculate often
ysr@777 908 size_t rs_lengths_prediction = rs_lengths * 1100 / 1000;
ysr@777 909 calculate_young_list_target_config(rs_lengths_prediction);
ysr@777 910 }
ysr@777 911 }
ysr@777 912
ysr@777 913 HeapWord* G1CollectorPolicy::mem_allocate_work(size_t size,
ysr@777 914 bool is_tlab,
ysr@777 915 bool* gc_overhead_limit_was_exceeded) {
ysr@777 916 guarantee(false, "Not using this policy feature yet.");
ysr@777 917 return NULL;
ysr@777 918 }
ysr@777 919
ysr@777 920 // This method controls how a collector handles one or more
ysr@777 921 // of its generations being fully allocated.
ysr@777 922 HeapWord* G1CollectorPolicy::satisfy_failed_allocation(size_t size,
ysr@777 923 bool is_tlab) {
ysr@777 924 guarantee(false, "Not using this policy feature yet.");
ysr@777 925 return NULL;
ysr@777 926 }
ysr@777 927
ysr@777 928
ysr@777 929 #ifndef PRODUCT
ysr@777 930 bool G1CollectorPolicy::verify_young_ages() {
ysr@777 931 HeapRegion* head = _g1->young_list_first_region();
ysr@777 932 return
ysr@777 933 verify_young_ages(head, _short_lived_surv_rate_group);
ysr@777 934 // also call verify_young_ages on any additional surv rate groups
ysr@777 935 }
ysr@777 936
ysr@777 937 bool
ysr@777 938 G1CollectorPolicy::verify_young_ages(HeapRegion* head,
ysr@777 939 SurvRateGroup *surv_rate_group) {
ysr@777 940 guarantee( surv_rate_group != NULL, "pre-condition" );
ysr@777 941
ysr@777 942 const char* name = surv_rate_group->name();
ysr@777 943 bool ret = true;
ysr@777 944 int prev_age = -1;
ysr@777 945
ysr@777 946 for (HeapRegion* curr = head;
ysr@777 947 curr != NULL;
ysr@777 948 curr = curr->get_next_young_region()) {
ysr@777 949 SurvRateGroup* group = curr->surv_rate_group();
ysr@777 950 if (group == NULL && !curr->is_survivor()) {
ysr@777 951 gclog_or_tty->print_cr("## %s: encountered NULL surv_rate_group", name);
ysr@777 952 ret = false;
ysr@777 953 }
ysr@777 954
ysr@777 955 if (surv_rate_group == group) {
ysr@777 956 int age = curr->age_in_surv_rate_group();
ysr@777 957
ysr@777 958 if (age < 0) {
ysr@777 959 gclog_or_tty->print_cr("## %s: encountered negative age", name);
ysr@777 960 ret = false;
ysr@777 961 }
ysr@777 962
ysr@777 963 if (age <= prev_age) {
ysr@777 964 gclog_or_tty->print_cr("## %s: region ages are not strictly increasing "
ysr@777 965 "(%d, %d)", name, age, prev_age);
ysr@777 966 ret = false;
ysr@777 967 }
ysr@777 968 prev_age = age;
ysr@777 969 }
ysr@777 970 }
ysr@777 971
ysr@777 972 return ret;
ysr@777 973 }
ysr@777 974 #endif // PRODUCT
ysr@777 975
ysr@777 976 void G1CollectorPolicy::record_full_collection_start() {
ysr@777 977 _cur_collection_start_sec = os::elapsedTime();
ysr@777 978 // Release the future to-space so that it is available for compaction into.
ysr@777 979 _g1->set_full_collection();
ysr@777 980 }
ysr@777 981
ysr@777 982 void G1CollectorPolicy::record_full_collection_end() {
ysr@777 983 // Consider this like a collection pause for the purposes of allocation
ysr@777 984 // since last pause.
ysr@777 985 double end_sec = os::elapsedTime();
ysr@777 986 double full_gc_time_sec = end_sec - _cur_collection_start_sec;
ysr@777 987 double full_gc_time_ms = full_gc_time_sec * 1000.0;
ysr@777 988
ysr@777 989 checkpoint_conc_overhead();
ysr@777 990
ysr@777 991 _all_full_gc_times_ms->add(full_gc_time_ms);
ysr@777 992
tonyp@1030 993 update_recent_gc_times(end_sec, full_gc_time_ms);
ysr@777 994
ysr@777 995 _g1->clear_full_collection();
ysr@777 996
ysr@777 997 // "Nuke" the heuristics that control the fully/partially young GC
ysr@777 998 // transitions and make sure we start with fully young GCs after the
ysr@777 999 // Full GC.
ysr@777 1000 set_full_young_gcs(true);
ysr@777 1001 _last_full_young_gc = false;
ysr@777 1002 _should_revert_to_full_young_gcs = false;
ysr@777 1003 _should_initiate_conc_mark = false;
ysr@777 1004 _known_garbage_bytes = 0;
ysr@777 1005 _known_garbage_ratio = 0.0;
ysr@777 1006 _in_marking_window = false;
ysr@777 1007 _in_marking_window_im = false;
ysr@777 1008
ysr@777 1009 _short_lived_surv_rate_group->record_scan_only_prefix(0);
ysr@777 1010 _short_lived_surv_rate_group->start_adding_regions();
ysr@777 1011 // also call this on any additional surv rate groups
ysr@777 1012
apetrusenko@980 1013 record_survivor_regions(0, NULL, NULL);
apetrusenko@980 1014
ysr@777 1015 _prev_region_num_young = _region_num_young;
ysr@777 1016 _prev_region_num_tenured = _region_num_tenured;
ysr@777 1017
ysr@777 1018 _free_regions_at_end_of_collection = _g1->free_regions();
ysr@777 1019 _scan_only_regions_at_end_of_collection = 0;
apetrusenko@980 1020 // Reset survivors SurvRateGroup.
apetrusenko@980 1021 _survivor_surv_rate_group->reset();
ysr@777 1022 calculate_young_list_min_length();
ysr@777 1023 calculate_young_list_target_config();
ysr@777 1024 }
ysr@777 1025
ysr@777 1026 void G1CollectorPolicy::record_before_bytes(size_t bytes) {
ysr@777 1027 _bytes_in_to_space_before_gc += bytes;
ysr@777 1028 }
ysr@777 1029
ysr@777 1030 void G1CollectorPolicy::record_after_bytes(size_t bytes) {
ysr@777 1031 _bytes_in_to_space_after_gc += bytes;
ysr@777 1032 }
ysr@777 1033
ysr@777 1034 void G1CollectorPolicy::record_stop_world_start() {
ysr@777 1035 _stop_world_start = os::elapsedTime();
ysr@777 1036 }
ysr@777 1037
ysr@777 1038 void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
ysr@777 1039 size_t start_used) {
ysr@777 1040 if (PrintGCDetails) {
ysr@777 1041 gclog_or_tty->stamp(PrintGCTimeStamps);
ysr@777 1042 gclog_or_tty->print("[GC pause");
ysr@777 1043 if (in_young_gc_mode())
ysr@777 1044 gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial");
ysr@777 1045 }
ysr@777 1046
ysr@777 1047 assert(_g1->used_regions() == _g1->recalculate_used_regions(),
ysr@777 1048 "sanity");
tonyp@1071 1049 assert(_g1->used() == _g1->recalculate_used(), "sanity");
ysr@777 1050
ysr@777 1051 double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0;
ysr@777 1052 _all_stop_world_times_ms->add(s_w_t_ms);
ysr@777 1053 _stop_world_start = 0.0;
ysr@777 1054
ysr@777 1055 _cur_collection_start_sec = start_time_sec;
ysr@777 1056 _cur_collection_pause_used_at_start_bytes = start_used;
ysr@777 1057 _cur_collection_pause_used_regions_at_start = _g1->used_regions();
ysr@777 1058 _pending_cards = _g1->pending_card_num();
ysr@777 1059 _max_pending_cards = _g1->max_pending_card_num();
ysr@777 1060
ysr@777 1061 _bytes_in_to_space_before_gc = 0;
ysr@777 1062 _bytes_in_to_space_after_gc = 0;
ysr@777 1063 _bytes_in_collection_set_before_gc = 0;
ysr@777 1064
ysr@777 1065 #ifdef DEBUG
ysr@777 1066 // initialise these to something well known so that we can spot
ysr@777 1067 // if they are not set properly
ysr@777 1068
ysr@777 1069 for (int i = 0; i < _parallel_gc_threads; ++i) {
ysr@777 1070 _par_last_ext_root_scan_times_ms[i] = -666.0;
ysr@777 1071 _par_last_mark_stack_scan_times_ms[i] = -666.0;
ysr@777 1072 _par_last_scan_only_times_ms[i] = -666.0;
ysr@777 1073 _par_last_scan_only_regions_scanned[i] = -666.0;
ysr@777 1074 _par_last_update_rs_start_times_ms[i] = -666.0;
ysr@777 1075 _par_last_update_rs_times_ms[i] = -666.0;
ysr@777 1076 _par_last_update_rs_processed_buffers[i] = -666.0;
ysr@777 1077 _par_last_scan_rs_start_times_ms[i] = -666.0;
ysr@777 1078 _par_last_scan_rs_times_ms[i] = -666.0;
ysr@777 1079 _par_last_scan_new_refs_times_ms[i] = -666.0;
ysr@777 1080 _par_last_obj_copy_times_ms[i] = -666.0;
ysr@777 1081 _par_last_termination_times_ms[i] = -666.0;
ysr@777 1082 }
ysr@777 1083 #endif
ysr@777 1084
ysr@777 1085 for (int i = 0; i < _aux_num; ++i) {
ysr@777 1086 _cur_aux_times_ms[i] = 0.0;
ysr@777 1087 _cur_aux_times_set[i] = false;
ysr@777 1088 }
ysr@777 1089
ysr@777 1090 _satb_drain_time_set = false;
ysr@777 1091 _last_satb_drain_processed_buffers = -1;
ysr@777 1092
ysr@777 1093 if (in_young_gc_mode())
ysr@777 1094 _last_young_gc_full = false;
ysr@777 1095
ysr@777 1096
ysr@777 1097 // do that for any other surv rate groups
ysr@777 1098 _short_lived_surv_rate_group->stop_adding_regions();
ysr@777 1099 size_t short_lived_so_length = _young_list_so_prefix_length;
ysr@777 1100 _short_lived_surv_rate_group->record_scan_only_prefix(short_lived_so_length);
ysr@777 1101 tag_scan_only(short_lived_so_length);
ysr@777 1102
johnc@1186 1103 if (G1UseSurvivorSpaces) {
apetrusenko@980 1104 _survivors_age_table.clear();
apetrusenko@980 1105 }
apetrusenko@980 1106
ysr@777 1107 assert( verify_young_ages(), "region age verification" );
ysr@777 1108 }
ysr@777 1109
ysr@777 1110 void G1CollectorPolicy::tag_scan_only(size_t short_lived_scan_only_length) {
ysr@777 1111 // done in a way that it can be extended for other surv rate groups too...
ysr@777 1112
ysr@777 1113 HeapRegion* head = _g1->young_list_first_region();
ysr@777 1114 bool finished_short_lived = (short_lived_scan_only_length == 0);
ysr@777 1115
ysr@777 1116 if (finished_short_lived)
ysr@777 1117 return;
ysr@777 1118
ysr@777 1119 for (HeapRegion* curr = head;
ysr@777 1120 curr != NULL;
ysr@777 1121 curr = curr->get_next_young_region()) {
ysr@777 1122 SurvRateGroup* surv_rate_group = curr->surv_rate_group();
ysr@777 1123 int age = curr->age_in_surv_rate_group();
ysr@777 1124
ysr@777 1125 if (surv_rate_group == _short_lived_surv_rate_group) {
ysr@777 1126 if ((size_t)age < short_lived_scan_only_length)
ysr@777 1127 curr->set_scan_only();
ysr@777 1128 else
ysr@777 1129 finished_short_lived = true;
ysr@777 1130 }
ysr@777 1131
ysr@777 1132
ysr@777 1133 if (finished_short_lived)
ysr@777 1134 return;
ysr@777 1135 }
ysr@777 1136
ysr@777 1137 guarantee( false, "we should never reach here" );
ysr@777 1138 }
ysr@777 1139
ysr@777 1140 void G1CollectorPolicy::record_mark_closure_time(double mark_closure_time_ms) {
ysr@777 1141 _mark_closure_time_ms = mark_closure_time_ms;
ysr@777 1142 }
ysr@777 1143
ysr@777 1144 void G1CollectorPolicy::record_concurrent_mark_init_start() {
ysr@777 1145 _mark_init_start_sec = os::elapsedTime();
ysr@777 1146 guarantee(!in_young_gc_mode(), "should not do be here in young GC mode");
ysr@777 1147 }
ysr@777 1148
ysr@777 1149 void G1CollectorPolicy::record_concurrent_mark_init_end_pre(double
ysr@777 1150 mark_init_elapsed_time_ms) {
ysr@777 1151 _during_marking = true;
ysr@777 1152 _should_initiate_conc_mark = false;
ysr@777 1153 _cur_mark_stop_world_time_ms = mark_init_elapsed_time_ms;
ysr@777 1154 }
ysr@777 1155
ysr@777 1156 void G1CollectorPolicy::record_concurrent_mark_init_end() {
ysr@777 1157 double end_time_sec = os::elapsedTime();
ysr@777 1158 double elapsed_time_ms = (end_time_sec - _mark_init_start_sec) * 1000.0;
ysr@777 1159 _concurrent_mark_init_times_ms->add(elapsed_time_ms);
ysr@777 1160 checkpoint_conc_overhead();
ysr@777 1161 record_concurrent_mark_init_end_pre(elapsed_time_ms);
ysr@777 1162
ysr@777 1163 _mmu_tracker->add_pause(_mark_init_start_sec, end_time_sec, true);
ysr@777 1164 }
ysr@777 1165
ysr@777 1166 void G1CollectorPolicy::record_concurrent_mark_remark_start() {
ysr@777 1167 _mark_remark_start_sec = os::elapsedTime();
ysr@777 1168 _during_marking = false;
ysr@777 1169 }
ysr@777 1170
ysr@777 1171 void G1CollectorPolicy::record_concurrent_mark_remark_end() {
ysr@777 1172 double end_time_sec = os::elapsedTime();
ysr@777 1173 double elapsed_time_ms = (end_time_sec - _mark_remark_start_sec)*1000.0;
ysr@777 1174 checkpoint_conc_overhead();
ysr@777 1175 _concurrent_mark_remark_times_ms->add(elapsed_time_ms);
ysr@777 1176 _cur_mark_stop_world_time_ms += elapsed_time_ms;
ysr@777 1177 _prev_collection_pause_end_ms += elapsed_time_ms;
ysr@777 1178
ysr@777 1179 _mmu_tracker->add_pause(_mark_remark_start_sec, end_time_sec, true);
ysr@777 1180 }
ysr@777 1181
ysr@777 1182 void G1CollectorPolicy::record_concurrent_mark_cleanup_start() {
ysr@777 1183 _mark_cleanup_start_sec = os::elapsedTime();
ysr@777 1184 }
ysr@777 1185
ysr@777 1186 void
ysr@777 1187 G1CollectorPolicy::record_concurrent_mark_cleanup_end(size_t freed_bytes,
ysr@777 1188 size_t max_live_bytes) {
ysr@777 1189 record_concurrent_mark_cleanup_end_work1(freed_bytes, max_live_bytes);
ysr@777 1190 record_concurrent_mark_cleanup_end_work2();
ysr@777 1191 }
ysr@777 1192
ysr@777 1193 void
ysr@777 1194 G1CollectorPolicy::
ysr@777 1195 record_concurrent_mark_cleanup_end_work1(size_t freed_bytes,
ysr@777 1196 size_t max_live_bytes) {
ysr@777 1197 if (_n_marks < 2) _n_marks++;
ysr@777 1198 if (G1PolicyVerbose > 0)
ysr@777 1199 gclog_or_tty->print_cr("At end of marking, max_live is " SIZE_FORMAT " MB "
ysr@777 1200 " (of " SIZE_FORMAT " MB heap).",
ysr@777 1201 max_live_bytes/M, _g1->capacity()/M);
ysr@777 1202 }
ysr@777 1203
ysr@777 1204 // The important thing about this is that it includes "os::elapsedTime".
ysr@777 1205 void G1CollectorPolicy::record_concurrent_mark_cleanup_end_work2() {
ysr@777 1206 checkpoint_conc_overhead();
ysr@777 1207 double end_time_sec = os::elapsedTime();
ysr@777 1208 double elapsed_time_ms = (end_time_sec - _mark_cleanup_start_sec)*1000.0;
ysr@777 1209 _concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
ysr@777 1210 _cur_mark_stop_world_time_ms += elapsed_time_ms;
ysr@777 1211 _prev_collection_pause_end_ms += elapsed_time_ms;
ysr@777 1212
ysr@777 1213 _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_time_sec, true);
ysr@777 1214
ysr@777 1215 _num_markings++;
ysr@777 1216
ysr@777 1217 // We did a marking, so reset the "since_last_mark" variables.
ysr@777 1218 double considerConcMarkCost = 1.0;
ysr@777 1219 // If there are available processors, concurrent activity is free...
ysr@777 1220 if (Threads::number_of_non_daemon_threads() * 2 <
ysr@777 1221 os::active_processor_count()) {
ysr@777 1222 considerConcMarkCost = 0.0;
ysr@777 1223 }
ysr@777 1224 _n_pauses_at_mark_end = _n_pauses;
ysr@777 1225 _n_marks_since_last_pause++;
ysr@777 1226 _conc_mark_initiated = false;
ysr@777 1227 }
ysr@777 1228
ysr@777 1229 void
ysr@777 1230 G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
ysr@777 1231 if (in_young_gc_mode()) {
ysr@777 1232 _should_revert_to_full_young_gcs = false;
ysr@777 1233 _last_full_young_gc = true;
ysr@777 1234 _in_marking_window = false;
ysr@777 1235 if (adaptive_young_list_length())
ysr@777 1236 calculate_young_list_target_config();
ysr@777 1237 }
ysr@777 1238 }
ysr@777 1239
ysr@777 1240 void G1CollectorPolicy::record_concurrent_pause() {
ysr@777 1241 if (_stop_world_start > 0.0) {
ysr@777 1242 double yield_ms = (os::elapsedTime() - _stop_world_start) * 1000.0;
ysr@777 1243 _all_yield_times_ms->add(yield_ms);
ysr@777 1244 }
ysr@777 1245 }
ysr@777 1246
ysr@777 1247 void G1CollectorPolicy::record_concurrent_pause_end() {
ysr@777 1248 }
ysr@777 1249
ysr@777 1250 void G1CollectorPolicy::record_collection_pause_end_CH_strong_roots() {
ysr@777 1251 _cur_CH_strong_roots_end_sec = os::elapsedTime();
ysr@777 1252 _cur_CH_strong_roots_dur_ms =
ysr@777 1253 (_cur_CH_strong_roots_end_sec - _cur_collection_start_sec) * 1000.0;
ysr@777 1254 }
ysr@777 1255
ysr@777 1256 void G1CollectorPolicy::record_collection_pause_end_G1_strong_roots() {
ysr@777 1257 _cur_G1_strong_roots_end_sec = os::elapsedTime();
ysr@777 1258 _cur_G1_strong_roots_dur_ms =
ysr@777 1259 (_cur_G1_strong_roots_end_sec - _cur_CH_strong_roots_end_sec) * 1000.0;
ysr@777 1260 }
ysr@777 1261
ysr@777 1262 template<class T>
ysr@777 1263 T sum_of(T* sum_arr, int start, int n, int N) {
ysr@777 1264 T sum = (T)0;
ysr@777 1265 for (int i = 0; i < n; i++) {
ysr@777 1266 int j = (start + i) % N;
ysr@777 1267 sum += sum_arr[j];
ysr@777 1268 }
ysr@777 1269 return sum;
ysr@777 1270 }
ysr@777 1271
ysr@777 1272 void G1CollectorPolicy::print_par_stats (int level,
ysr@777 1273 const char* str,
ysr@777 1274 double* data,
ysr@777 1275 bool summary) {
ysr@777 1276 double min = data[0], max = data[0];
ysr@777 1277 double total = 0.0;
ysr@777 1278 int j;
ysr@777 1279 for (j = 0; j < level; ++j)
ysr@777 1280 gclog_or_tty->print(" ");
ysr@777 1281 gclog_or_tty->print("[%s (ms):", str);
ysr@777 1282 for (uint i = 0; i < ParallelGCThreads; ++i) {
ysr@777 1283 double val = data[i];
ysr@777 1284 if (val < min)
ysr@777 1285 min = val;
ysr@777 1286 if (val > max)
ysr@777 1287 max = val;
ysr@777 1288 total += val;
ysr@777 1289 gclog_or_tty->print(" %3.1lf", val);
ysr@777 1290 }
ysr@777 1291 if (summary) {
ysr@777 1292 gclog_or_tty->print_cr("");
ysr@777 1293 double avg = total / (double) ParallelGCThreads;
ysr@777 1294 gclog_or_tty->print(" ");
ysr@777 1295 for (j = 0; j < level; ++j)
ysr@777 1296 gclog_or_tty->print(" ");
ysr@777 1297 gclog_or_tty->print("Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf",
ysr@777 1298 avg, min, max);
ysr@777 1299 }
ysr@777 1300 gclog_or_tty->print_cr("]");
ysr@777 1301 }
ysr@777 1302
ysr@777 1303 void G1CollectorPolicy::print_par_buffers (int level,
ysr@777 1304 const char* str,
ysr@777 1305 double* data,
ysr@777 1306 bool summary) {
ysr@777 1307 double min = data[0], max = data[0];
ysr@777 1308 double total = 0.0;
ysr@777 1309 int j;
ysr@777 1310 for (j = 0; j < level; ++j)
ysr@777 1311 gclog_or_tty->print(" ");
ysr@777 1312 gclog_or_tty->print("[%s :", str);
ysr@777 1313 for (uint i = 0; i < ParallelGCThreads; ++i) {
ysr@777 1314 double val = data[i];
ysr@777 1315 if (val < min)
ysr@777 1316 min = val;
ysr@777 1317 if (val > max)
ysr@777 1318 max = val;
ysr@777 1319 total += val;
ysr@777 1320 gclog_or_tty->print(" %d", (int) val);
ysr@777 1321 }
ysr@777 1322 if (summary) {
ysr@777 1323 gclog_or_tty->print_cr("");
ysr@777 1324 double avg = total / (double) ParallelGCThreads;
ysr@777 1325 gclog_or_tty->print(" ");
ysr@777 1326 for (j = 0; j < level; ++j)
ysr@777 1327 gclog_or_tty->print(" ");
ysr@777 1328 gclog_or_tty->print("Sum: %d, Avg: %d, Min: %d, Max: %d",
ysr@777 1329 (int)total, (int)avg, (int)min, (int)max);
ysr@777 1330 }
ysr@777 1331 gclog_or_tty->print_cr("]");
ysr@777 1332 }
ysr@777 1333
ysr@777 1334 void G1CollectorPolicy::print_stats (int level,
ysr@777 1335 const char* str,
ysr@777 1336 double value) {
ysr@777 1337 for (int j = 0; j < level; ++j)
ysr@777 1338 gclog_or_tty->print(" ");
ysr@777 1339 gclog_or_tty->print_cr("[%s: %5.1lf ms]", str, value);
ysr@777 1340 }
ysr@777 1341
ysr@777 1342 void G1CollectorPolicy::print_stats (int level,
ysr@777 1343 const char* str,
ysr@777 1344 int value) {
ysr@777 1345 for (int j = 0; j < level; ++j)
ysr@777 1346 gclog_or_tty->print(" ");
ysr@777 1347 gclog_or_tty->print_cr("[%s: %d]", str, value);
ysr@777 1348 }
ysr@777 1349
ysr@777 1350 double G1CollectorPolicy::avg_value (double* data) {
ysr@777 1351 if (ParallelGCThreads > 0) {
ysr@777 1352 double ret = 0.0;
ysr@777 1353 for (uint i = 0; i < ParallelGCThreads; ++i)
ysr@777 1354 ret += data[i];
ysr@777 1355 return ret / (double) ParallelGCThreads;
ysr@777 1356 } else {
ysr@777 1357 return data[0];
ysr@777 1358 }
ysr@777 1359 }
ysr@777 1360
ysr@777 1361 double G1CollectorPolicy::max_value (double* data) {
ysr@777 1362 if (ParallelGCThreads > 0) {
ysr@777 1363 double ret = data[0];
ysr@777 1364 for (uint i = 1; i < ParallelGCThreads; ++i)
ysr@777 1365 if (data[i] > ret)
ysr@777 1366 ret = data[i];
ysr@777 1367 return ret;
ysr@777 1368 } else {
ysr@777 1369 return data[0];
ysr@777 1370 }
ysr@777 1371 }
ysr@777 1372
ysr@777 1373 double G1CollectorPolicy::sum_of_values (double* data) {
ysr@777 1374 if (ParallelGCThreads > 0) {
ysr@777 1375 double sum = 0.0;
ysr@777 1376 for (uint i = 0; i < ParallelGCThreads; i++)
ysr@777 1377 sum += data[i];
ysr@777 1378 return sum;
ysr@777 1379 } else {
ysr@777 1380 return data[0];
ysr@777 1381 }
ysr@777 1382 }
ysr@777 1383
ysr@777 1384 double G1CollectorPolicy::max_sum (double* data1,
ysr@777 1385 double* data2) {
ysr@777 1386 double ret = data1[0] + data2[0];
ysr@777 1387
ysr@777 1388 if (ParallelGCThreads > 0) {
ysr@777 1389 for (uint i = 1; i < ParallelGCThreads; ++i) {
ysr@777 1390 double data = data1[i] + data2[i];
ysr@777 1391 if (data > ret)
ysr@777 1392 ret = data;
ysr@777 1393 }
ysr@777 1394 }
ysr@777 1395 return ret;
ysr@777 1396 }
ysr@777 1397
ysr@777 1398 // Anything below that is considered to be zero
ysr@777 1399 #define MIN_TIMER_GRANULARITY 0.0000001
ysr@777 1400
apetrusenko@1112 1401 void G1CollectorPolicy::record_collection_pause_end(bool abandoned) {
ysr@777 1402 double end_time_sec = os::elapsedTime();
ysr@777 1403 double elapsed_ms = _last_pause_time_ms;
ysr@777 1404 bool parallel = ParallelGCThreads > 0;
ysr@777 1405 double evac_ms = (end_time_sec - _cur_G1_strong_roots_end_sec) * 1000.0;
ysr@777 1406 size_t rs_size =
ysr@777 1407 _cur_collection_pause_used_regions_at_start - collection_set_size();
ysr@777 1408 size_t cur_used_bytes = _g1->used();
ysr@777 1409 assert(cur_used_bytes == _g1->recalculate_used(), "It should!");
ysr@777 1410 bool last_pause_included_initial_mark = false;
tonyp@1030 1411 bool update_stats = !abandoned && !_g1->evacuation_failed();
ysr@777 1412
ysr@777 1413 #ifndef PRODUCT
ysr@777 1414 if (G1YoungSurvRateVerbose) {
ysr@777 1415 gclog_or_tty->print_cr("");
ysr@777 1416 _short_lived_surv_rate_group->print();
ysr@777 1417 // do that for any other surv rate groups too
ysr@777 1418 }
ysr@777 1419 #endif // PRODUCT
ysr@777 1420
ysr@777 1421 checkpoint_conc_overhead();
ysr@777 1422
ysr@777 1423 if (in_young_gc_mode()) {
ysr@777 1424 last_pause_included_initial_mark = _should_initiate_conc_mark;
ysr@777 1425 if (last_pause_included_initial_mark)
ysr@777 1426 record_concurrent_mark_init_end_pre(0.0);
ysr@777 1427
ysr@777 1428 size_t min_used_targ =
ysr@777 1429 (_g1->capacity() / 100) * (G1SteadyStateUsed - G1SteadyStateUsedDelta);
ysr@777 1430
ysr@777 1431 if (cur_used_bytes > min_used_targ) {
ysr@777 1432 if (cur_used_bytes <= _prev_collection_pause_used_at_end_bytes) {
ysr@777 1433 } else if (!_g1->mark_in_progress() && !_last_full_young_gc) {
ysr@777 1434 _should_initiate_conc_mark = true;
ysr@777 1435 }
ysr@777 1436 }
ysr@777 1437
ysr@777 1438 _prev_collection_pause_used_at_end_bytes = cur_used_bytes;
ysr@777 1439 }
ysr@777 1440
ysr@777 1441 _mmu_tracker->add_pause(end_time_sec - elapsed_ms/1000.0,
ysr@777 1442 end_time_sec, false);
ysr@777 1443
ysr@777 1444 guarantee(_cur_collection_pause_used_regions_at_start >=
ysr@777 1445 collection_set_size(),
ysr@777 1446 "Negative RS size?");
ysr@777 1447
ysr@777 1448 // This assert is exempted when we're doing parallel collection pauses,
ysr@777 1449 // because the fragmentation caused by the parallel GC allocation buffers
ysr@777 1450 // can lead to more memory being used during collection than was used
ysr@777 1451 // before. Best leave this out until the fragmentation problem is fixed.
ysr@777 1452 // Pauses in which evacuation failed can also lead to negative
ysr@777 1453 // collections, since no space is reclaimed from a region containing an
ysr@777 1454 // object whose evacuation failed.
ysr@777 1455 // Further, we're now always doing parallel collection. But I'm still
ysr@777 1456 // leaving this here as a placeholder for a more precise assertion later.
ysr@777 1457 // (DLD, 10/05.)
ysr@777 1458 assert((true || parallel) // Always using GC LABs now.
ysr@777 1459 || _g1->evacuation_failed()
ysr@777 1460 || _cur_collection_pause_used_at_start_bytes >= cur_used_bytes,
ysr@777 1461 "Negative collection");
ysr@777 1462
ysr@777 1463 size_t freed_bytes =
ysr@777 1464 _cur_collection_pause_used_at_start_bytes - cur_used_bytes;
ysr@777 1465 size_t surviving_bytes = _collection_set_bytes_used_before - freed_bytes;
ysr@777 1466 double survival_fraction =
ysr@777 1467 (double)surviving_bytes/
ysr@777 1468 (double)_collection_set_bytes_used_before;
ysr@777 1469
ysr@777 1470 _n_pauses++;
ysr@777 1471
tonyp@1030 1472 if (update_stats) {
ysr@777 1473 _recent_CH_strong_roots_times_ms->add(_cur_CH_strong_roots_dur_ms);
ysr@777 1474 _recent_G1_strong_roots_times_ms->add(_cur_G1_strong_roots_dur_ms);
ysr@777 1475 _recent_evac_times_ms->add(evac_ms);
ysr@777 1476 _recent_pause_times_ms->add(elapsed_ms);
ysr@777 1477
ysr@777 1478 _recent_rs_sizes->add(rs_size);
ysr@777 1479
ysr@777 1480 // We exempt parallel collection from this check because Alloc Buffer
ysr@777 1481 // fragmentation can produce negative collections. Same with evac
ysr@777 1482 // failure.
ysr@777 1483 // Further, we're now always doing parallel collection. But I'm still
ysr@777 1484 // leaving this here as a placeholder for a more precise assertion later.
ysr@777 1485 // (DLD, 10/05.
ysr@777 1486 assert((true || parallel)
ysr@777 1487 || _g1->evacuation_failed()
ysr@777 1488 || surviving_bytes <= _collection_set_bytes_used_before,
ysr@777 1489 "Or else negative collection!");
ysr@777 1490 _recent_CS_bytes_used_before->add(_collection_set_bytes_used_before);
ysr@777 1491 _recent_CS_bytes_surviving->add(surviving_bytes);
ysr@777 1492
ysr@777 1493 // this is where we update the allocation rate of the application
ysr@777 1494 double app_time_ms =
ysr@777 1495 (_cur_collection_start_sec * 1000.0 - _prev_collection_pause_end_ms);
ysr@777 1496 if (app_time_ms < MIN_TIMER_GRANULARITY) {
ysr@777 1497 // This usually happens due to the timer not having the required
ysr@777 1498 // granularity. Some Linuxes are the usual culprits.
ysr@777 1499 // We'll just set it to something (arbitrarily) small.
ysr@777 1500 app_time_ms = 1.0;
ysr@777 1501 }
ysr@777 1502 size_t regions_allocated =
ysr@777 1503 (_region_num_young - _prev_region_num_young) +
ysr@777 1504 (_region_num_tenured - _prev_region_num_tenured);
ysr@777 1505 double alloc_rate_ms = (double) regions_allocated / app_time_ms;
ysr@777 1506 _alloc_rate_ms_seq->add(alloc_rate_ms);
ysr@777 1507 _prev_region_num_young = _region_num_young;
ysr@777 1508 _prev_region_num_tenured = _region_num_tenured;
ysr@777 1509
ysr@777 1510 double interval_ms =
ysr@777 1511 (end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0;
ysr@777 1512 update_recent_gc_times(end_time_sec, elapsed_ms);
ysr@777 1513 _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms;
ysr@777 1514 assert(recent_avg_pause_time_ratio() < 1.00, "All GC?");
ysr@777 1515 }
ysr@777 1516
ysr@777 1517 if (G1PolicyVerbose > 1) {
ysr@777 1518 gclog_or_tty->print_cr(" Recording collection pause(%d)", _n_pauses);
ysr@777 1519 }
ysr@777 1520
ysr@777 1521 PauseSummary* summary;
apetrusenko@1112 1522 if (abandoned) {
apetrusenko@1112 1523 summary = _abandoned_summary;
apetrusenko@1112 1524 } else {
apetrusenko@1112 1525 summary = _summary;
ysr@777 1526 }
ysr@777 1527
ysr@777 1528 double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms);
ysr@777 1529 double mark_stack_scan_time = avg_value(_par_last_mark_stack_scan_times_ms);
ysr@777 1530 double scan_only_time = avg_value(_par_last_scan_only_times_ms);
ysr@777 1531 double scan_only_regions_scanned =
ysr@777 1532 sum_of_values(_par_last_scan_only_regions_scanned);
ysr@777 1533 double update_rs_time = avg_value(_par_last_update_rs_times_ms);
ysr@777 1534 double update_rs_processed_buffers =
ysr@777 1535 sum_of_values(_par_last_update_rs_processed_buffers);
ysr@777 1536 double scan_rs_time = avg_value(_par_last_scan_rs_times_ms);
ysr@777 1537 double obj_copy_time = avg_value(_par_last_obj_copy_times_ms);
ysr@777 1538 double termination_time = avg_value(_par_last_termination_times_ms);
ysr@777 1539
tonyp@1083 1540 double parallel_other_time = _cur_collection_par_time_ms -
tonyp@1083 1541 (update_rs_time + ext_root_scan_time + mark_stack_scan_time +
tonyp@1083 1542 scan_only_time + scan_rs_time + obj_copy_time + termination_time);
tonyp@1030 1543 if (update_stats) {
ysr@777 1544 MainBodySummary* body_summary = summary->main_body_summary();
ysr@777 1545 guarantee(body_summary != NULL, "should not be null!");
ysr@777 1546
ysr@777 1547 if (_satb_drain_time_set)
ysr@777 1548 body_summary->record_satb_drain_time_ms(_cur_satb_drain_time_ms);
ysr@777 1549 else
ysr@777 1550 body_summary->record_satb_drain_time_ms(0.0);
ysr@777 1551 body_summary->record_ext_root_scan_time_ms(ext_root_scan_time);
ysr@777 1552 body_summary->record_mark_stack_scan_time_ms(mark_stack_scan_time);
ysr@777 1553 body_summary->record_scan_only_time_ms(scan_only_time);
ysr@777 1554 body_summary->record_update_rs_time_ms(update_rs_time);
ysr@777 1555 body_summary->record_scan_rs_time_ms(scan_rs_time);
ysr@777 1556 body_summary->record_obj_copy_time_ms(obj_copy_time);
ysr@777 1557 if (parallel) {
ysr@777 1558 body_summary->record_parallel_time_ms(_cur_collection_par_time_ms);
ysr@777 1559 body_summary->record_clear_ct_time_ms(_cur_clear_ct_time_ms);
ysr@777 1560 body_summary->record_termination_time_ms(termination_time);
ysr@777 1561 body_summary->record_parallel_other_time_ms(parallel_other_time);
ysr@777 1562 }
ysr@777 1563 body_summary->record_mark_closure_time_ms(_mark_closure_time_ms);
ysr@777 1564 }
ysr@777 1565
ysr@777 1566 if (G1PolicyVerbose > 1) {
ysr@777 1567 gclog_or_tty->print_cr(" ET: %10.6f ms (avg: %10.6f ms)\n"
ysr@777 1568 " CH Strong: %10.6f ms (avg: %10.6f ms)\n"
ysr@777 1569 " G1 Strong: %10.6f ms (avg: %10.6f ms)\n"
ysr@777 1570 " Evac: %10.6f ms (avg: %10.6f ms)\n"
ysr@777 1571 " ET-RS: %10.6f ms (avg: %10.6f ms)\n"
ysr@777 1572 " |RS|: " SIZE_FORMAT,
ysr@777 1573 elapsed_ms, recent_avg_time_for_pauses_ms(),
ysr@777 1574 _cur_CH_strong_roots_dur_ms, recent_avg_time_for_CH_strong_ms(),
ysr@777 1575 _cur_G1_strong_roots_dur_ms, recent_avg_time_for_G1_strong_ms(),
ysr@777 1576 evac_ms, recent_avg_time_for_evac_ms(),
ysr@777 1577 scan_rs_time,
ysr@777 1578 recent_avg_time_for_pauses_ms() -
ysr@777 1579 recent_avg_time_for_G1_strong_ms(),
ysr@777 1580 rs_size);
ysr@777 1581
ysr@777 1582 gclog_or_tty->print_cr(" Used at start: " SIZE_FORMAT"K"
ysr@777 1583 " At end " SIZE_FORMAT "K\n"
ysr@777 1584 " garbage : " SIZE_FORMAT "K"
ysr@777 1585 " of " SIZE_FORMAT "K\n"
ysr@777 1586 " survival : %6.2f%% (%6.2f%% avg)",
ysr@777 1587 _cur_collection_pause_used_at_start_bytes/K,
ysr@777 1588 _g1->used()/K, freed_bytes/K,
ysr@777 1589 _collection_set_bytes_used_before/K,
ysr@777 1590 survival_fraction*100.0,
ysr@777 1591 recent_avg_survival_fraction()*100.0);
ysr@777 1592 gclog_or_tty->print_cr(" Recent %% gc pause time: %6.2f",
ysr@777 1593 recent_avg_pause_time_ratio() * 100.0);
ysr@777 1594 }
ysr@777 1595
ysr@777 1596 double other_time_ms = elapsed_ms;
ysr@777 1597
ysr@777 1598 if (!abandoned) {
ysr@777 1599 if (_satb_drain_time_set)
ysr@777 1600 other_time_ms -= _cur_satb_drain_time_ms;
ysr@777 1601
ysr@777 1602 if (parallel)
ysr@777 1603 other_time_ms -= _cur_collection_par_time_ms + _cur_clear_ct_time_ms;
ysr@777 1604 else
ysr@777 1605 other_time_ms -=
ysr@777 1606 update_rs_time +
ysr@777 1607 ext_root_scan_time + mark_stack_scan_time + scan_only_time +
ysr@777 1608 scan_rs_time + obj_copy_time;
ysr@777 1609 }
ysr@777 1610
ysr@777 1611 if (PrintGCDetails) {
ysr@777 1612 gclog_or_tty->print_cr("%s%s, %1.8lf secs]",
apetrusenko@1112 1613 abandoned ? " (abandoned)" : "",
ysr@777 1614 (last_pause_included_initial_mark) ? " (initial-mark)" : "",
ysr@777 1615 elapsed_ms / 1000.0);
ysr@777 1616
ysr@777 1617 if (!abandoned) {
apetrusenko@1112 1618 if (_satb_drain_time_set) {
ysr@777 1619 print_stats(1, "SATB Drain Time", _cur_satb_drain_time_ms);
apetrusenko@1112 1620 }
apetrusenko@1112 1621 if (_last_satb_drain_processed_buffers >= 0) {
ysr@777 1622 print_stats(2, "Processed Buffers", _last_satb_drain_processed_buffers);
apetrusenko@1112 1623 }
apetrusenko@1112 1624 if (parallel) {
apetrusenko@1112 1625 print_stats(1, "Parallel Time", _cur_collection_par_time_ms);
apetrusenko@1112 1626 print_par_stats(2, "Update RS (Start)", _par_last_update_rs_start_times_ms, false);
apetrusenko@1112 1627 print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
iveresov@1229 1628 print_par_buffers(3, "Processed Buffers",
iveresov@1229 1629 _par_last_update_rs_processed_buffers, true);
ysr@777 1630 print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
ysr@777 1631 print_par_stats(2, "Mark Stack Scanning", _par_last_mark_stack_scan_times_ms);
ysr@777 1632 print_par_stats(2, "Scan-Only Scanning", _par_last_scan_only_times_ms);
ysr@777 1633 print_par_buffers(3, "Scan-Only Regions",
ysr@777 1634 _par_last_scan_only_regions_scanned, true);
ysr@777 1635 print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms);
ysr@777 1636 print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms);
ysr@777 1637 print_par_stats(2, "Termination", _par_last_termination_times_ms);
ysr@777 1638 print_stats(2, "Other", parallel_other_time);
ysr@777 1639 print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
apetrusenko@1112 1640 } else {
apetrusenko@1112 1641 print_stats(1, "Update RS", update_rs_time);
iveresov@1229 1642 print_stats(2, "Processed Buffers",
iveresov@1229 1643 (int)update_rs_processed_buffers);
ysr@777 1644 print_stats(1, "Ext Root Scanning", ext_root_scan_time);
ysr@777 1645 print_stats(1, "Mark Stack Scanning", mark_stack_scan_time);
ysr@777 1646 print_stats(1, "Scan-Only Scanning", scan_only_time);
ysr@777 1647 print_stats(1, "Scan RS", scan_rs_time);
ysr@777 1648 print_stats(1, "Object Copying", obj_copy_time);
ysr@777 1649 }
ysr@777 1650 }
ysr@777 1651 print_stats(1, "Other", other_time_ms);
ysr@777 1652 for (int i = 0; i < _aux_num; ++i) {
ysr@777 1653 if (_cur_aux_times_set[i]) {
ysr@777 1654 char buffer[96];
ysr@777 1655 sprintf(buffer, "Aux%d", i);
ysr@777 1656 print_stats(1, buffer, _cur_aux_times_ms[i]);
ysr@777 1657 }
ysr@777 1658 }
ysr@777 1659 }
ysr@777 1660 if (PrintGCDetails)
ysr@777 1661 gclog_or_tty->print(" [");
ysr@777 1662 if (PrintGC || PrintGCDetails)
ysr@777 1663 _g1->print_size_transition(gclog_or_tty,
ysr@777 1664 _cur_collection_pause_used_at_start_bytes,
ysr@777 1665 _g1->used(), _g1->capacity());
ysr@777 1666 if (PrintGCDetails)
ysr@777 1667 gclog_or_tty->print_cr("]");
ysr@777 1668
ysr@777 1669 _all_pause_times_ms->add(elapsed_ms);
tonyp@1083 1670 if (update_stats) {
tonyp@1083 1671 summary->record_total_time_ms(elapsed_ms);
tonyp@1083 1672 summary->record_other_time_ms(other_time_ms);
tonyp@1083 1673 }
ysr@777 1674 for (int i = 0; i < _aux_num; ++i)
ysr@777 1675 if (_cur_aux_times_set[i])
ysr@777 1676 _all_aux_times_ms[i].add(_cur_aux_times_ms[i]);
ysr@777 1677
ysr@777 1678 // Reset marks-between-pauses counter.
ysr@777 1679 _n_marks_since_last_pause = 0;
ysr@777 1680
ysr@777 1681 // Update the efficiency-since-mark vars.
ysr@777 1682 double proc_ms = elapsed_ms * (double) _parallel_gc_threads;
ysr@777 1683 if (elapsed_ms < MIN_TIMER_GRANULARITY) {
ysr@777 1684 // This usually happens due to the timer not having the required
ysr@777 1685 // granularity. Some Linuxes are the usual culprits.
ysr@777 1686 // We'll just set it to something (arbitrarily) small.
ysr@777 1687 proc_ms = 1.0;
ysr@777 1688 }
ysr@777 1689 double cur_efficiency = (double) freed_bytes / proc_ms;
ysr@777 1690
ysr@777 1691 bool new_in_marking_window = _in_marking_window;
ysr@777 1692 bool new_in_marking_window_im = false;
ysr@777 1693 if (_should_initiate_conc_mark) {
ysr@777 1694 new_in_marking_window = true;
ysr@777 1695 new_in_marking_window_im = true;
ysr@777 1696 }
ysr@777 1697
ysr@777 1698 if (in_young_gc_mode()) {
ysr@777 1699 if (_last_full_young_gc) {
ysr@777 1700 set_full_young_gcs(false);
ysr@777 1701 _last_full_young_gc = false;
ysr@777 1702 }
ysr@777 1703
ysr@777 1704 if ( !_last_young_gc_full ) {
ysr@777 1705 if ( _should_revert_to_full_young_gcs ||
ysr@777 1706 _known_garbage_ratio < 0.05 ||
ysr@777 1707 (adaptive_young_list_length() &&
ysr@777 1708 (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) ) {
ysr@777 1709 set_full_young_gcs(true);
ysr@777 1710 }
ysr@777 1711 }
ysr@777 1712 _should_revert_to_full_young_gcs = false;
ysr@777 1713
ysr@777 1714 if (_last_young_gc_full && !_during_marking)
ysr@777 1715 _young_gc_eff_seq->add(cur_efficiency);
ysr@777 1716 }
ysr@777 1717
ysr@777 1718 _short_lived_surv_rate_group->start_adding_regions();
ysr@777 1719 // do that for any other surv rate groupsx
ysr@777 1720
ysr@777 1721 // <NEW PREDICTION>
ysr@777 1722
apetrusenko@1112 1723 if (update_stats) {
ysr@777 1724 double pause_time_ms = elapsed_ms;
ysr@777 1725
ysr@777 1726 size_t diff = 0;
ysr@777 1727 if (_max_pending_cards >= _pending_cards)
ysr@777 1728 diff = _max_pending_cards - _pending_cards;
ysr@777 1729 _pending_card_diff_seq->add((double) diff);
ysr@777 1730
ysr@777 1731 double cost_per_card_ms = 0.0;
ysr@777 1732 if (_pending_cards > 0) {
ysr@777 1733 cost_per_card_ms = update_rs_time / (double) _pending_cards;
ysr@777 1734 _cost_per_card_ms_seq->add(cost_per_card_ms);
ysr@777 1735 }
ysr@777 1736
ysr@777 1737 double cost_per_scan_only_region_ms = 0.0;
ysr@777 1738 if (scan_only_regions_scanned > 0.0) {
ysr@777 1739 cost_per_scan_only_region_ms =
ysr@777 1740 scan_only_time / scan_only_regions_scanned;
ysr@777 1741 if (_in_marking_window_im)
ysr@777 1742 _cost_per_scan_only_region_ms_during_cm_seq->add(cost_per_scan_only_region_ms);
ysr@777 1743 else
ysr@777 1744 _cost_per_scan_only_region_ms_seq->add(cost_per_scan_only_region_ms);
ysr@777 1745 }
ysr@777 1746
ysr@777 1747 size_t cards_scanned = _g1->cards_scanned();
ysr@777 1748
ysr@777 1749 double cost_per_entry_ms = 0.0;
ysr@777 1750 if (cards_scanned > 10) {
ysr@777 1751 cost_per_entry_ms = scan_rs_time / (double) cards_scanned;
ysr@777 1752 if (_last_young_gc_full)
ysr@777 1753 _cost_per_entry_ms_seq->add(cost_per_entry_ms);
ysr@777 1754 else
ysr@777 1755 _partially_young_cost_per_entry_ms_seq->add(cost_per_entry_ms);
ysr@777 1756 }
ysr@777 1757
ysr@777 1758 if (_max_rs_lengths > 0) {
ysr@777 1759 double cards_per_entry_ratio =
ysr@777 1760 (double) cards_scanned / (double) _max_rs_lengths;
ysr@777 1761 if (_last_young_gc_full)
ysr@777 1762 _fully_young_cards_per_entry_ratio_seq->add(cards_per_entry_ratio);
ysr@777 1763 else
ysr@777 1764 _partially_young_cards_per_entry_ratio_seq->add(cards_per_entry_ratio);
ysr@777 1765 }
ysr@777 1766
ysr@777 1767 size_t rs_length_diff = _max_rs_lengths - _recorded_rs_lengths;
ysr@777 1768 if (rs_length_diff >= 0)
ysr@777 1769 _rs_length_diff_seq->add((double) rs_length_diff);
ysr@777 1770
ysr@777 1771 size_t copied_bytes = surviving_bytes;
ysr@777 1772 double cost_per_byte_ms = 0.0;
ysr@777 1773 if (copied_bytes > 0) {
ysr@777 1774 cost_per_byte_ms = obj_copy_time / (double) copied_bytes;
ysr@777 1775 if (_in_marking_window)
ysr@777 1776 _cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
ysr@777 1777 else
ysr@777 1778 _cost_per_byte_ms_seq->add(cost_per_byte_ms);
ysr@777 1779 }
ysr@777 1780
ysr@777 1781 double all_other_time_ms = pause_time_ms -
ysr@777 1782 (update_rs_time + scan_only_time + scan_rs_time + obj_copy_time +
ysr@777 1783 _mark_closure_time_ms + termination_time);
ysr@777 1784
ysr@777 1785 double young_other_time_ms = 0.0;
ysr@777 1786 if (_recorded_young_regions > 0) {
ysr@777 1787 young_other_time_ms =
ysr@777 1788 _recorded_young_cset_choice_time_ms +
ysr@777 1789 _recorded_young_free_cset_time_ms;
ysr@777 1790 _young_other_cost_per_region_ms_seq->add(young_other_time_ms /
ysr@777 1791 (double) _recorded_young_regions);
ysr@777 1792 }
ysr@777 1793 double non_young_other_time_ms = 0.0;
ysr@777 1794 if (_recorded_non_young_regions > 0) {
ysr@777 1795 non_young_other_time_ms =
ysr@777 1796 _recorded_non_young_cset_choice_time_ms +
ysr@777 1797 _recorded_non_young_free_cset_time_ms;
ysr@777 1798
ysr@777 1799 _non_young_other_cost_per_region_ms_seq->add(non_young_other_time_ms /
ysr@777 1800 (double) _recorded_non_young_regions);
ysr@777 1801 }
ysr@777 1802
ysr@777 1803 double constant_other_time_ms = all_other_time_ms -
ysr@777 1804 (young_other_time_ms + non_young_other_time_ms);
ysr@777 1805 _constant_other_time_ms_seq->add(constant_other_time_ms);
ysr@777 1806
ysr@777 1807 double survival_ratio = 0.0;
ysr@777 1808 if (_bytes_in_collection_set_before_gc > 0) {
ysr@777 1809 survival_ratio = (double) bytes_in_to_space_during_gc() /
ysr@777 1810 (double) _bytes_in_collection_set_before_gc;
ysr@777 1811 }
ysr@777 1812
ysr@777 1813 _pending_cards_seq->add((double) _pending_cards);
ysr@777 1814 _scanned_cards_seq->add((double) cards_scanned);
ysr@777 1815 _rs_lengths_seq->add((double) _max_rs_lengths);
ysr@777 1816
ysr@777 1817 double expensive_region_limit_ms =
johnc@1186 1818 (double) MaxGCPauseMillis - predict_constant_other_time_ms();
ysr@777 1819 if (expensive_region_limit_ms < 0.0) {
ysr@777 1820 // this means that the other time was predicted to be longer than
ysr@777 1821 // than the max pause time
johnc@1186 1822 expensive_region_limit_ms = (double) MaxGCPauseMillis;
ysr@777 1823 }
ysr@777 1824 _expensive_region_limit_ms = expensive_region_limit_ms;
ysr@777 1825
ysr@777 1826 if (PREDICTIONS_VERBOSE) {
ysr@777 1827 gclog_or_tty->print_cr("");
ysr@777 1828 gclog_or_tty->print_cr("PREDICTIONS %1.4lf %d "
ysr@777 1829 "REGIONS %d %d %d %d "
ysr@777 1830 "PENDING_CARDS %d %d "
ysr@777 1831 "CARDS_SCANNED %d %d "
ysr@777 1832 "RS_LENGTHS %d %d "
ysr@777 1833 "SCAN_ONLY_SCAN %1.6lf %1.6lf "
ysr@777 1834 "RS_UPDATE %1.6lf %1.6lf RS_SCAN %1.6lf %1.6lf "
ysr@777 1835 "SURVIVAL_RATIO %1.6lf %1.6lf "
ysr@777 1836 "OBJECT_COPY %1.6lf %1.6lf OTHER_CONSTANT %1.6lf %1.6lf "
ysr@777 1837 "OTHER_YOUNG %1.6lf %1.6lf "
ysr@777 1838 "OTHER_NON_YOUNG %1.6lf %1.6lf "
ysr@777 1839 "VTIME_DIFF %1.6lf TERMINATION %1.6lf "
ysr@777 1840 "ELAPSED %1.6lf %1.6lf ",
ysr@777 1841 _cur_collection_start_sec,
ysr@777 1842 (!_last_young_gc_full) ? 2 :
ysr@777 1843 (last_pause_included_initial_mark) ? 1 : 0,
ysr@777 1844 _recorded_region_num,
ysr@777 1845 _recorded_young_regions,
ysr@777 1846 _recorded_scan_only_regions,
ysr@777 1847 _recorded_non_young_regions,
ysr@777 1848 _predicted_pending_cards, _pending_cards,
ysr@777 1849 _predicted_cards_scanned, cards_scanned,
ysr@777 1850 _predicted_rs_lengths, _max_rs_lengths,
ysr@777 1851 _predicted_scan_only_scan_time_ms, scan_only_time,
ysr@777 1852 _predicted_rs_update_time_ms, update_rs_time,
ysr@777 1853 _predicted_rs_scan_time_ms, scan_rs_time,
ysr@777 1854 _predicted_survival_ratio, survival_ratio,
ysr@777 1855 _predicted_object_copy_time_ms, obj_copy_time,
ysr@777 1856 _predicted_constant_other_time_ms, constant_other_time_ms,
ysr@777 1857 _predicted_young_other_time_ms, young_other_time_ms,
ysr@777 1858 _predicted_non_young_other_time_ms,
ysr@777 1859 non_young_other_time_ms,
ysr@777 1860 _vtime_diff_ms, termination_time,
ysr@777 1861 _predicted_pause_time_ms, elapsed_ms);
ysr@777 1862 }
ysr@777 1863
ysr@777 1864 if (G1PolicyVerbose > 0) {
ysr@777 1865 gclog_or_tty->print_cr("Pause Time, predicted: %1.4lfms (predicted %s), actual: %1.4lfms",
ysr@777 1866 _predicted_pause_time_ms,
ysr@777 1867 (_within_target) ? "within" : "outside",
ysr@777 1868 elapsed_ms);
ysr@777 1869 }
ysr@777 1870
ysr@777 1871 }
ysr@777 1872
ysr@777 1873 _in_marking_window = new_in_marking_window;
ysr@777 1874 _in_marking_window_im = new_in_marking_window_im;
ysr@777 1875 _free_regions_at_end_of_collection = _g1->free_regions();
ysr@777 1876 _scan_only_regions_at_end_of_collection = _g1->young_list_length();
ysr@777 1877 calculate_young_list_min_length();
ysr@777 1878 calculate_young_list_target_config();
ysr@777 1879
ysr@777 1880 // </NEW PREDICTION>
ysr@777 1881
ysr@777 1882 _target_pause_time_ms = -1.0;
ysr@777 1883 }
ysr@777 1884
ysr@777 1885 // <NEW PREDICTION>
ysr@777 1886
ysr@777 1887 double
ysr@777 1888 G1CollectorPolicy::
ysr@777 1889 predict_young_collection_elapsed_time_ms(size_t adjustment) {
ysr@777 1890 guarantee( adjustment == 0 || adjustment == 1, "invariant" );
ysr@777 1891
ysr@777 1892 G1CollectedHeap* g1h = G1CollectedHeap::heap();
ysr@777 1893 size_t young_num = g1h->young_list_length();
ysr@777 1894 if (young_num == 0)
ysr@777 1895 return 0.0;
ysr@777 1896
ysr@777 1897 young_num += adjustment;
ysr@777 1898 size_t pending_cards = predict_pending_cards();
ysr@777 1899 size_t rs_lengths = g1h->young_list_sampled_rs_lengths() +
ysr@777 1900 predict_rs_length_diff();
ysr@777 1901 size_t card_num;
ysr@777 1902 if (full_young_gcs())
ysr@777 1903 card_num = predict_young_card_num(rs_lengths);
ysr@777 1904 else
ysr@777 1905 card_num = predict_non_young_card_num(rs_lengths);
ysr@777 1906 size_t young_byte_size = young_num * HeapRegion::GrainBytes;
ysr@777 1907 double accum_yg_surv_rate =
ysr@777 1908 _short_lived_surv_rate_group->accum_surv_rate(adjustment);
ysr@777 1909
ysr@777 1910 size_t bytes_to_copy =
ysr@777 1911 (size_t) (accum_yg_surv_rate * (double) HeapRegion::GrainBytes);
ysr@777 1912
ysr@777 1913 return
ysr@777 1914 predict_rs_update_time_ms(pending_cards) +
ysr@777 1915 predict_rs_scan_time_ms(card_num) +
ysr@777 1916 predict_object_copy_time_ms(bytes_to_copy) +
ysr@777 1917 predict_young_other_time_ms(young_num) +
ysr@777 1918 predict_constant_other_time_ms();
ysr@777 1919 }
ysr@777 1920
ysr@777 1921 double
ysr@777 1922 G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards) {
ysr@777 1923 size_t rs_length = predict_rs_length_diff();
ysr@777 1924 size_t card_num;
ysr@777 1925 if (full_young_gcs())
ysr@777 1926 card_num = predict_young_card_num(rs_length);
ysr@777 1927 else
ysr@777 1928 card_num = predict_non_young_card_num(rs_length);
ysr@777 1929 return predict_base_elapsed_time_ms(pending_cards, card_num);
ysr@777 1930 }
ysr@777 1931
ysr@777 1932 double
ysr@777 1933 G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards,
ysr@777 1934 size_t scanned_cards) {
ysr@777 1935 return
ysr@777 1936 predict_rs_update_time_ms(pending_cards) +
ysr@777 1937 predict_rs_scan_time_ms(scanned_cards) +
ysr@777 1938 predict_constant_other_time_ms();
ysr@777 1939 }
ysr@777 1940
ysr@777 1941 double
ysr@777 1942 G1CollectorPolicy::predict_region_elapsed_time_ms(HeapRegion* hr,
ysr@777 1943 bool young) {
ysr@777 1944 size_t rs_length = hr->rem_set()->occupied();
ysr@777 1945 size_t card_num;
ysr@777 1946 if (full_young_gcs())
ysr@777 1947 card_num = predict_young_card_num(rs_length);
ysr@777 1948 else
ysr@777 1949 card_num = predict_non_young_card_num(rs_length);
ysr@777 1950 size_t bytes_to_copy = predict_bytes_to_copy(hr);
ysr@777 1951
ysr@777 1952 double region_elapsed_time_ms =
ysr@777 1953 predict_rs_scan_time_ms(card_num) +
ysr@777 1954 predict_object_copy_time_ms(bytes_to_copy);
ysr@777 1955
ysr@777 1956 if (young)
ysr@777 1957 region_elapsed_time_ms += predict_young_other_time_ms(1);
ysr@777 1958 else
ysr@777 1959 region_elapsed_time_ms += predict_non_young_other_time_ms(1);
ysr@777 1960
ysr@777 1961 return region_elapsed_time_ms;
ysr@777 1962 }
ysr@777 1963
ysr@777 1964 size_t
ysr@777 1965 G1CollectorPolicy::predict_bytes_to_copy(HeapRegion* hr) {
ysr@777 1966 size_t bytes_to_copy;
ysr@777 1967 if (hr->is_marked())
ysr@777 1968 bytes_to_copy = hr->max_live_bytes();
ysr@777 1969 else {
ysr@777 1970 guarantee( hr->is_young() && hr->age_in_surv_rate_group() != -1,
ysr@777 1971 "invariant" );
ysr@777 1972 int age = hr->age_in_surv_rate_group();
apetrusenko@980 1973 double yg_surv_rate = predict_yg_surv_rate(age, hr->surv_rate_group());
ysr@777 1974 bytes_to_copy = (size_t) ((double) hr->used() * yg_surv_rate);
ysr@777 1975 }
ysr@777 1976
ysr@777 1977 return bytes_to_copy;
ysr@777 1978 }
ysr@777 1979
ysr@777 1980 void
ysr@777 1981 G1CollectorPolicy::start_recording_regions() {
ysr@777 1982 _recorded_rs_lengths = 0;
ysr@777 1983 _recorded_scan_only_regions = 0;
ysr@777 1984 _recorded_young_regions = 0;
ysr@777 1985 _recorded_non_young_regions = 0;
ysr@777 1986
ysr@777 1987 #if PREDICTIONS_VERBOSE
ysr@777 1988 _predicted_rs_lengths = 0;
ysr@777 1989 _predicted_cards_scanned = 0;
ysr@777 1990
ysr@777 1991 _recorded_marked_bytes = 0;
ysr@777 1992 _recorded_young_bytes = 0;
ysr@777 1993 _predicted_bytes_to_copy = 0;
ysr@777 1994 #endif // PREDICTIONS_VERBOSE
ysr@777 1995 }
ysr@777 1996
ysr@777 1997 void
ysr@777 1998 G1CollectorPolicy::record_cset_region(HeapRegion* hr, bool young) {
ysr@777 1999 if (young) {
ysr@777 2000 ++_recorded_young_regions;
ysr@777 2001 } else {
ysr@777 2002 ++_recorded_non_young_regions;
ysr@777 2003 }
ysr@777 2004 #if PREDICTIONS_VERBOSE
ysr@777 2005 if (young) {
apetrusenko@980 2006 _recorded_young_bytes += hr->used();
ysr@777 2007 } else {
ysr@777 2008 _recorded_marked_bytes += hr->max_live_bytes();
ysr@777 2009 }
ysr@777 2010 _predicted_bytes_to_copy += predict_bytes_to_copy(hr);
ysr@777 2011 #endif // PREDICTIONS_VERBOSE
ysr@777 2012
ysr@777 2013 size_t rs_length = hr->rem_set()->occupied();
ysr@777 2014 _recorded_rs_lengths += rs_length;
ysr@777 2015 }
ysr@777 2016
ysr@777 2017 void
ysr@777 2018 G1CollectorPolicy::record_scan_only_regions(size_t scan_only_length) {
ysr@777 2019 _recorded_scan_only_regions = scan_only_length;
ysr@777 2020 }
ysr@777 2021
ysr@777 2022 void
ysr@777 2023 G1CollectorPolicy::end_recording_regions() {
ysr@777 2024 #if PREDICTIONS_VERBOSE
ysr@777 2025 _predicted_pending_cards = predict_pending_cards();
ysr@777 2026 _predicted_rs_lengths = _recorded_rs_lengths + predict_rs_length_diff();
ysr@777 2027 if (full_young_gcs())
ysr@777 2028 _predicted_cards_scanned += predict_young_card_num(_predicted_rs_lengths);
ysr@777 2029 else
ysr@777 2030 _predicted_cards_scanned +=
ysr@777 2031 predict_non_young_card_num(_predicted_rs_lengths);
ysr@777 2032 _recorded_region_num = _recorded_young_regions + _recorded_non_young_regions;
ysr@777 2033
ysr@777 2034 _predicted_scan_only_scan_time_ms =
ysr@777 2035 predict_scan_only_time_ms(_recorded_scan_only_regions);
ysr@777 2036 _predicted_rs_update_time_ms =
ysr@777 2037 predict_rs_update_time_ms(_g1->pending_card_num());
ysr@777 2038 _predicted_rs_scan_time_ms =
ysr@777 2039 predict_rs_scan_time_ms(_predicted_cards_scanned);
ysr@777 2040 _predicted_object_copy_time_ms =
ysr@777 2041 predict_object_copy_time_ms(_predicted_bytes_to_copy);
ysr@777 2042 _predicted_constant_other_time_ms =
ysr@777 2043 predict_constant_other_time_ms();
ysr@777 2044 _predicted_young_other_time_ms =
ysr@777 2045 predict_young_other_time_ms(_recorded_young_regions);
ysr@777 2046 _predicted_non_young_other_time_ms =
ysr@777 2047 predict_non_young_other_time_ms(_recorded_non_young_regions);
ysr@777 2048
ysr@777 2049 _predicted_pause_time_ms =
ysr@777 2050 _predicted_scan_only_scan_time_ms +
ysr@777 2051 _predicted_rs_update_time_ms +
ysr@777 2052 _predicted_rs_scan_time_ms +
ysr@777 2053 _predicted_object_copy_time_ms +
ysr@777 2054 _predicted_constant_other_time_ms +
ysr@777 2055 _predicted_young_other_time_ms +
ysr@777 2056 _predicted_non_young_other_time_ms;
ysr@777 2057 #endif // PREDICTIONS_VERBOSE
ysr@777 2058 }
ysr@777 2059
ysr@777 2060 void G1CollectorPolicy::check_if_region_is_too_expensive(double
ysr@777 2061 predicted_time_ms) {
ysr@777 2062 // I don't think we need to do this when in young GC mode since
ysr@777 2063 // marking will be initiated next time we hit the soft limit anyway...
ysr@777 2064 if (predicted_time_ms > _expensive_region_limit_ms) {
ysr@777 2065 if (!in_young_gc_mode()) {
ysr@777 2066 set_full_young_gcs(true);
ysr@777 2067 _should_initiate_conc_mark = true;
ysr@777 2068 } else
ysr@777 2069 // no point in doing another partial one
ysr@777 2070 _should_revert_to_full_young_gcs = true;
ysr@777 2071 }
ysr@777 2072 }
ysr@777 2073
ysr@777 2074 // </NEW PREDICTION>
ysr@777 2075
ysr@777 2076
ysr@777 2077 void G1CollectorPolicy::update_recent_gc_times(double end_time_sec,
ysr@777 2078 double elapsed_ms) {
ysr@777 2079 _recent_gc_times_ms->add(elapsed_ms);
ysr@777 2080 _recent_prev_end_times_for_all_gcs_sec->add(end_time_sec);
ysr@777 2081 _prev_collection_pause_end_ms = end_time_sec * 1000.0;
ysr@777 2082 }
ysr@777 2083
ysr@777 2084 double G1CollectorPolicy::recent_avg_time_for_pauses_ms() {
johnc@1186 2085 if (_recent_pause_times_ms->num() == 0) return (double) MaxGCPauseMillis;
ysr@777 2086 else return _recent_pause_times_ms->avg();
ysr@777 2087 }
ysr@777 2088
ysr@777 2089 double G1CollectorPolicy::recent_avg_time_for_CH_strong_ms() {
ysr@777 2090 if (_recent_CH_strong_roots_times_ms->num() == 0)
johnc@1186 2091 return (double)MaxGCPauseMillis/3.0;
ysr@777 2092 else return _recent_CH_strong_roots_times_ms->avg();
ysr@777 2093 }
ysr@777 2094
ysr@777 2095 double G1CollectorPolicy::recent_avg_time_for_G1_strong_ms() {
ysr@777 2096 if (_recent_G1_strong_roots_times_ms->num() == 0)
johnc@1186 2097 return (double)MaxGCPauseMillis/3.0;
ysr@777 2098 else return _recent_G1_strong_roots_times_ms->avg();
ysr@777 2099 }
ysr@777 2100
ysr@777 2101 double G1CollectorPolicy::recent_avg_time_for_evac_ms() {
johnc@1186 2102 if (_recent_evac_times_ms->num() == 0) return (double)MaxGCPauseMillis/3.0;
ysr@777 2103 else return _recent_evac_times_ms->avg();
ysr@777 2104 }
ysr@777 2105
ysr@777 2106 int G1CollectorPolicy::number_of_recent_gcs() {
ysr@777 2107 assert(_recent_CH_strong_roots_times_ms->num() ==
ysr@777 2108 _recent_G1_strong_roots_times_ms->num(), "Sequence out of sync");
ysr@777 2109 assert(_recent_G1_strong_roots_times_ms->num() ==
ysr@777 2110 _recent_evac_times_ms->num(), "Sequence out of sync");
ysr@777 2111 assert(_recent_evac_times_ms->num() ==
ysr@777 2112 _recent_pause_times_ms->num(), "Sequence out of sync");
ysr@777 2113 assert(_recent_pause_times_ms->num() ==
ysr@777 2114 _recent_CS_bytes_used_before->num(), "Sequence out of sync");
ysr@777 2115 assert(_recent_CS_bytes_used_before->num() ==
ysr@777 2116 _recent_CS_bytes_surviving->num(), "Sequence out of sync");
ysr@777 2117 return _recent_pause_times_ms->num();
ysr@777 2118 }
ysr@777 2119
ysr@777 2120 double G1CollectorPolicy::recent_avg_survival_fraction() {
ysr@777 2121 return recent_avg_survival_fraction_work(_recent_CS_bytes_surviving,
ysr@777 2122 _recent_CS_bytes_used_before);
ysr@777 2123 }
ysr@777 2124
ysr@777 2125 double G1CollectorPolicy::last_survival_fraction() {
ysr@777 2126 return last_survival_fraction_work(_recent_CS_bytes_surviving,
ysr@777 2127 _recent_CS_bytes_used_before);
ysr@777 2128 }
ysr@777 2129
ysr@777 2130 double
ysr@777 2131 G1CollectorPolicy::recent_avg_survival_fraction_work(TruncatedSeq* surviving,
ysr@777 2132 TruncatedSeq* before) {
ysr@777 2133 assert(surviving->num() == before->num(), "Sequence out of sync");
ysr@777 2134 if (before->sum() > 0.0) {
ysr@777 2135 double recent_survival_rate = surviving->sum() / before->sum();
ysr@777 2136 // We exempt parallel collection from this check because Alloc Buffer
ysr@777 2137 // fragmentation can produce negative collections.
ysr@777 2138 // Further, we're now always doing parallel collection. But I'm still
ysr@777 2139 // leaving this here as a placeholder for a more precise assertion later.
ysr@777 2140 // (DLD, 10/05.)
ysr@777 2141 assert((true || ParallelGCThreads > 0) ||
ysr@777 2142 _g1->evacuation_failed() ||
ysr@777 2143 recent_survival_rate <= 1.0, "Or bad frac");
ysr@777 2144 return recent_survival_rate;
ysr@777 2145 } else {
ysr@777 2146 return 1.0; // Be conservative.
ysr@777 2147 }
ysr@777 2148 }
ysr@777 2149
ysr@777 2150 double
ysr@777 2151 G1CollectorPolicy::last_survival_fraction_work(TruncatedSeq* surviving,
ysr@777 2152 TruncatedSeq* before) {
ysr@777 2153 assert(surviving->num() == before->num(), "Sequence out of sync");
ysr@777 2154 if (surviving->num() > 0 && before->last() > 0.0) {
ysr@777 2155 double last_survival_rate = surviving->last() / before->last();
ysr@777 2156 // We exempt parallel collection from this check because Alloc Buffer
ysr@777 2157 // fragmentation can produce negative collections.
ysr@777 2158 // Further, we're now always doing parallel collection. But I'm still
ysr@777 2159 // leaving this here as a placeholder for a more precise assertion later.
ysr@777 2160 // (DLD, 10/05.)
ysr@777 2161 assert((true || ParallelGCThreads > 0) ||
ysr@777 2162 last_survival_rate <= 1.0, "Or bad frac");
ysr@777 2163 return last_survival_rate;
ysr@777 2164 } else {
ysr@777 2165 return 1.0;
ysr@777 2166 }
ysr@777 2167 }
ysr@777 2168
ysr@777 2169 static const int survival_min_obs = 5;
ysr@777 2170 static double survival_min_obs_limits[] = { 0.9, 0.7, 0.5, 0.3, 0.1 };
ysr@777 2171 static const double min_survival_rate = 0.1;
ysr@777 2172
ysr@777 2173 double
ysr@777 2174 G1CollectorPolicy::conservative_avg_survival_fraction_work(double avg,
ysr@777 2175 double latest) {
ysr@777 2176 double res = avg;
ysr@777 2177 if (number_of_recent_gcs() < survival_min_obs) {
ysr@777 2178 res = MAX2(res, survival_min_obs_limits[number_of_recent_gcs()]);
ysr@777 2179 }
ysr@777 2180 res = MAX2(res, latest);
ysr@777 2181 res = MAX2(res, min_survival_rate);
ysr@777 2182 // In the parallel case, LAB fragmentation can produce "negative
ysr@777 2183 // collections"; so can evac failure. Cap at 1.0
ysr@777 2184 res = MIN2(res, 1.0);
ysr@777 2185 return res;
ysr@777 2186 }
ysr@777 2187
ysr@777 2188 size_t G1CollectorPolicy::expansion_amount() {
johnc@1186 2189 if ((int)(recent_avg_pause_time_ratio() * 100.0) > G1GCPercent) {
johnc@1186 2190 // We will double the existing space, or take
johnc@1186 2191 // G1ExpandByPercentOfAvailable % of the available expansion
johnc@1186 2192 // space, whichever is smaller, bounded below by a minimum
johnc@1186 2193 // expansion (unless that's all that's left.)
ysr@777 2194 const size_t min_expand_bytes = 1*M;
ysr@777 2195 size_t reserved_bytes = _g1->g1_reserved_obj_bytes();
ysr@777 2196 size_t committed_bytes = _g1->capacity();
ysr@777 2197 size_t uncommitted_bytes = reserved_bytes - committed_bytes;
ysr@777 2198 size_t expand_bytes;
ysr@777 2199 size_t expand_bytes_via_pct =
johnc@1186 2200 uncommitted_bytes * G1ExpandByPercentOfAvailable / 100;
ysr@777 2201 expand_bytes = MIN2(expand_bytes_via_pct, committed_bytes);
ysr@777 2202 expand_bytes = MAX2(expand_bytes, min_expand_bytes);
ysr@777 2203 expand_bytes = MIN2(expand_bytes, uncommitted_bytes);
ysr@777 2204 if (G1PolicyVerbose > 1) {
ysr@777 2205 gclog_or_tty->print("Decided to expand: ratio = %5.2f, "
ysr@777 2206 "committed = %d%s, uncommited = %d%s, via pct = %d%s.\n"
ysr@777 2207 " Answer = %d.\n",
ysr@777 2208 recent_avg_pause_time_ratio(),
ysr@777 2209 byte_size_in_proper_unit(committed_bytes),
ysr@777 2210 proper_unit_for_byte_size(committed_bytes),
ysr@777 2211 byte_size_in_proper_unit(uncommitted_bytes),
ysr@777 2212 proper_unit_for_byte_size(uncommitted_bytes),
ysr@777 2213 byte_size_in_proper_unit(expand_bytes_via_pct),
ysr@777 2214 proper_unit_for_byte_size(expand_bytes_via_pct),
ysr@777 2215 byte_size_in_proper_unit(expand_bytes),
ysr@777 2216 proper_unit_for_byte_size(expand_bytes));
ysr@777 2217 }
ysr@777 2218 return expand_bytes;
ysr@777 2219 } else {
ysr@777 2220 return 0;
ysr@777 2221 }
ysr@777 2222 }
ysr@777 2223
ysr@777 2224 void G1CollectorPolicy::note_start_of_mark_thread() {
ysr@777 2225 _mark_thread_startup_sec = os::elapsedTime();
ysr@777 2226 }
ysr@777 2227
ysr@777 2228 class CountCSClosure: public HeapRegionClosure {
ysr@777 2229 G1CollectorPolicy* _g1_policy;
ysr@777 2230 public:
ysr@777 2231 CountCSClosure(G1CollectorPolicy* g1_policy) :
ysr@777 2232 _g1_policy(g1_policy) {}
ysr@777 2233 bool doHeapRegion(HeapRegion* r) {
ysr@777 2234 _g1_policy->_bytes_in_collection_set_before_gc += r->used();
ysr@777 2235 return false;
ysr@777 2236 }
ysr@777 2237 };
ysr@777 2238
ysr@777 2239 void G1CollectorPolicy::count_CS_bytes_used() {
ysr@777 2240 CountCSClosure cs_closure(this);
ysr@777 2241 _g1->collection_set_iterate(&cs_closure);
ysr@777 2242 }
ysr@777 2243
ysr@777 2244 static void print_indent(int level) {
ysr@777 2245 for (int j = 0; j < level+1; ++j)
ysr@777 2246 gclog_or_tty->print(" ");
ysr@777 2247 }
ysr@777 2248
ysr@777 2249 void G1CollectorPolicy::print_summary (int level,
ysr@777 2250 const char* str,
ysr@777 2251 NumberSeq* seq) const {
ysr@777 2252 double sum = seq->sum();
ysr@777 2253 print_indent(level);
ysr@777 2254 gclog_or_tty->print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
ysr@777 2255 str, sum / 1000.0, seq->avg());
ysr@777 2256 }
ysr@777 2257
ysr@777 2258 void G1CollectorPolicy::print_summary_sd (int level,
ysr@777 2259 const char* str,
ysr@777 2260 NumberSeq* seq) const {
ysr@777 2261 print_summary(level, str, seq);
ysr@777 2262 print_indent(level + 5);
ysr@777 2263 gclog_or_tty->print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
ysr@777 2264 seq->num(), seq->sd(), seq->maximum());
ysr@777 2265 }
ysr@777 2266
ysr@777 2267 void G1CollectorPolicy::check_other_times(int level,
ysr@777 2268 NumberSeq* other_times_ms,
ysr@777 2269 NumberSeq* calc_other_times_ms) const {
ysr@777 2270 bool should_print = false;
ysr@777 2271
ysr@777 2272 double max_sum = MAX2(fabs(other_times_ms->sum()),
ysr@777 2273 fabs(calc_other_times_ms->sum()));
ysr@777 2274 double min_sum = MIN2(fabs(other_times_ms->sum()),
ysr@777 2275 fabs(calc_other_times_ms->sum()));
ysr@777 2276 double sum_ratio = max_sum / min_sum;
ysr@777 2277 if (sum_ratio > 1.1) {
ysr@777 2278 should_print = true;
ysr@777 2279 print_indent(level + 1);
ysr@777 2280 gclog_or_tty->print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
ysr@777 2281 }
ysr@777 2282
ysr@777 2283 double max_avg = MAX2(fabs(other_times_ms->avg()),
ysr@777 2284 fabs(calc_other_times_ms->avg()));
ysr@777 2285 double min_avg = MIN2(fabs(other_times_ms->avg()),
ysr@777 2286 fabs(calc_other_times_ms->avg()));
ysr@777 2287 double avg_ratio = max_avg / min_avg;
ysr@777 2288 if (avg_ratio > 1.1) {
ysr@777 2289 should_print = true;
ysr@777 2290 print_indent(level + 1);
ysr@777 2291 gclog_or_tty->print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
ysr@777 2292 }
ysr@777 2293
ysr@777 2294 if (other_times_ms->sum() < -0.01) {
ysr@777 2295 print_indent(level + 1);
ysr@777 2296 gclog_or_tty->print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
ysr@777 2297 }
ysr@777 2298
ysr@777 2299 if (other_times_ms->avg() < -0.01) {
ysr@777 2300 print_indent(level + 1);
ysr@777 2301 gclog_or_tty->print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
ysr@777 2302 }
ysr@777 2303
ysr@777 2304 if (calc_other_times_ms->sum() < -0.01) {
ysr@777 2305 should_print = true;
ysr@777 2306 print_indent(level + 1);
ysr@777 2307 gclog_or_tty->print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
ysr@777 2308 }
ysr@777 2309
ysr@777 2310 if (calc_other_times_ms->avg() < -0.01) {
ysr@777 2311 should_print = true;
ysr@777 2312 print_indent(level + 1);
ysr@777 2313 gclog_or_tty->print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
ysr@777 2314 }
ysr@777 2315
ysr@777 2316 if (should_print)
ysr@777 2317 print_summary(level, "Other(Calc)", calc_other_times_ms);
ysr@777 2318 }
ysr@777 2319
ysr@777 2320 void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
ysr@777 2321 bool parallel = ParallelGCThreads > 0;
ysr@777 2322 MainBodySummary* body_summary = summary->main_body_summary();
ysr@777 2323 if (summary->get_total_seq()->num() > 0) {
apetrusenko@1112 2324 print_summary_sd(0, "Evacuation Pauses", summary->get_total_seq());
ysr@777 2325 if (body_summary != NULL) {
ysr@777 2326 print_summary(1, "SATB Drain", body_summary->get_satb_drain_seq());
ysr@777 2327 if (parallel) {
ysr@777 2328 print_summary(1, "Parallel Time", body_summary->get_parallel_seq());
ysr@777 2329 print_summary(2, "Update RS", body_summary->get_update_rs_seq());
ysr@777 2330 print_summary(2, "Ext Root Scanning",
ysr@777 2331 body_summary->get_ext_root_scan_seq());
ysr@777 2332 print_summary(2, "Mark Stack Scanning",
ysr@777 2333 body_summary->get_mark_stack_scan_seq());
ysr@777 2334 print_summary(2, "Scan-Only Scanning",
ysr@777 2335 body_summary->get_scan_only_seq());
ysr@777 2336 print_summary(2, "Scan RS", body_summary->get_scan_rs_seq());
ysr@777 2337 print_summary(2, "Object Copy", body_summary->get_obj_copy_seq());
ysr@777 2338 print_summary(2, "Termination", body_summary->get_termination_seq());
ysr@777 2339 print_summary(2, "Other", body_summary->get_parallel_other_seq());
ysr@777 2340 {
ysr@777 2341 NumberSeq* other_parts[] = {
ysr@777 2342 body_summary->get_update_rs_seq(),
ysr@777 2343 body_summary->get_ext_root_scan_seq(),
ysr@777 2344 body_summary->get_mark_stack_scan_seq(),
ysr@777 2345 body_summary->get_scan_only_seq(),
ysr@777 2346 body_summary->get_scan_rs_seq(),
ysr@777 2347 body_summary->get_obj_copy_seq(),
ysr@777 2348 body_summary->get_termination_seq()
ysr@777 2349 };
ysr@777 2350 NumberSeq calc_other_times_ms(body_summary->get_parallel_seq(),
ysr@777 2351 7, other_parts);
ysr@777 2352 check_other_times(2, body_summary->get_parallel_other_seq(),
ysr@777 2353 &calc_other_times_ms);
ysr@777 2354 }
ysr@777 2355 print_summary(1, "Mark Closure", body_summary->get_mark_closure_seq());
ysr@777 2356 print_summary(1, "Clear CT", body_summary->get_clear_ct_seq());
ysr@777 2357 } else {
ysr@777 2358 print_summary(1, "Update RS", body_summary->get_update_rs_seq());
ysr@777 2359 print_summary(1, "Ext Root Scanning",
ysr@777 2360 body_summary->get_ext_root_scan_seq());
ysr@777 2361 print_summary(1, "Mark Stack Scanning",
ysr@777 2362 body_summary->get_mark_stack_scan_seq());
ysr@777 2363 print_summary(1, "Scan-Only Scanning",
ysr@777 2364 body_summary->get_scan_only_seq());
ysr@777 2365 print_summary(1, "Scan RS", body_summary->get_scan_rs_seq());
ysr@777 2366 print_summary(1, "Object Copy", body_summary->get_obj_copy_seq());
ysr@777 2367 }
ysr@777 2368 }
ysr@777 2369 print_summary(1, "Other", summary->get_other_seq());
ysr@777 2370 {
ysr@777 2371 NumberSeq calc_other_times_ms;
ysr@777 2372 if (body_summary != NULL) {
ysr@777 2373 // not abandoned
ysr@777 2374 if (parallel) {
ysr@777 2375 // parallel
ysr@777 2376 NumberSeq* other_parts[] = {
ysr@777 2377 body_summary->get_satb_drain_seq(),
ysr@777 2378 body_summary->get_parallel_seq(),
ysr@777 2379 body_summary->get_clear_ct_seq()
ysr@777 2380 };
apetrusenko@1112 2381 calc_other_times_ms = NumberSeq(summary->get_total_seq(),
apetrusenko@1112 2382 3, other_parts);
ysr@777 2383 } else {
ysr@777 2384 // serial
ysr@777 2385 NumberSeq* other_parts[] = {
ysr@777 2386 body_summary->get_satb_drain_seq(),
ysr@777 2387 body_summary->get_update_rs_seq(),
ysr@777 2388 body_summary->get_ext_root_scan_seq(),
ysr@777 2389 body_summary->get_mark_stack_scan_seq(),
ysr@777 2390 body_summary->get_scan_only_seq(),
ysr@777 2391 body_summary->get_scan_rs_seq(),
ysr@777 2392 body_summary->get_obj_copy_seq()
ysr@777 2393 };
ysr@777 2394 calc_other_times_ms = NumberSeq(summary->get_total_seq(),
apetrusenko@1112 2395 7, other_parts);
ysr@777 2396 }
ysr@777 2397 } else {
ysr@777 2398 // abandoned
apetrusenko@1112 2399 calc_other_times_ms = NumberSeq();
ysr@777 2400 }
ysr@777 2401 check_other_times(1, summary->get_other_seq(), &calc_other_times_ms);
ysr@777 2402 }
ysr@777 2403 } else {
ysr@777 2404 print_indent(0);
ysr@777 2405 gclog_or_tty->print_cr("none");
ysr@777 2406 }
ysr@777 2407 gclog_or_tty->print_cr("");
ysr@777 2408 }
ysr@777 2409
ysr@777 2410 void
apetrusenko@1112 2411 G1CollectorPolicy::print_abandoned_summary(PauseSummary* summary) const {
ysr@777 2412 bool printed = false;
apetrusenko@1112 2413 if (summary->get_total_seq()->num() > 0) {
ysr@777 2414 printed = true;
apetrusenko@1112 2415 print_summary(summary);
ysr@777 2416 }
ysr@777 2417 if (!printed) {
ysr@777 2418 print_indent(0);
ysr@777 2419 gclog_or_tty->print_cr("none");
ysr@777 2420 gclog_or_tty->print_cr("");
ysr@777 2421 }
ysr@777 2422 }
ysr@777 2423
ysr@777 2424 void G1CollectorPolicy::print_tracing_info() const {
ysr@777 2425 if (TraceGen0Time) {
ysr@777 2426 gclog_or_tty->print_cr("ALL PAUSES");
ysr@777 2427 print_summary_sd(0, "Total", _all_pause_times_ms);
ysr@777 2428 gclog_or_tty->print_cr("");
ysr@777 2429 gclog_or_tty->print_cr("");
ysr@777 2430 gclog_or_tty->print_cr(" Full Young GC Pauses: %8d", _full_young_pause_num);
ysr@777 2431 gclog_or_tty->print_cr(" Partial Young GC Pauses: %8d", _partial_young_pause_num);
ysr@777 2432 gclog_or_tty->print_cr("");
ysr@777 2433
apetrusenko@1112 2434 gclog_or_tty->print_cr("EVACUATION PAUSES");
apetrusenko@1112 2435 print_summary(_summary);
ysr@777 2436
ysr@777 2437 gclog_or_tty->print_cr("ABANDONED PAUSES");
apetrusenko@1112 2438 print_abandoned_summary(_abandoned_summary);
ysr@777 2439
ysr@777 2440 gclog_or_tty->print_cr("MISC");
ysr@777 2441 print_summary_sd(0, "Stop World", _all_stop_world_times_ms);
ysr@777 2442 print_summary_sd(0, "Yields", _all_yield_times_ms);
ysr@777 2443 for (int i = 0; i < _aux_num; ++i) {
ysr@777 2444 if (_all_aux_times_ms[i].num() > 0) {
ysr@777 2445 char buffer[96];
ysr@777 2446 sprintf(buffer, "Aux%d", i);
ysr@777 2447 print_summary_sd(0, buffer, &_all_aux_times_ms[i]);
ysr@777 2448 }
ysr@777 2449 }
ysr@777 2450
ysr@777 2451 size_t all_region_num = _region_num_young + _region_num_tenured;
ysr@777 2452 gclog_or_tty->print_cr(" New Regions %8d, Young %8d (%6.2lf%%), "
ysr@777 2453 "Tenured %8d (%6.2lf%%)",
ysr@777 2454 all_region_num,
ysr@777 2455 _region_num_young,
ysr@777 2456 (double) _region_num_young / (double) all_region_num * 100.0,
ysr@777 2457 _region_num_tenured,
ysr@777 2458 (double) _region_num_tenured / (double) all_region_num * 100.0);
ysr@777 2459 }
ysr@777 2460 if (TraceGen1Time) {
ysr@777 2461 if (_all_full_gc_times_ms->num() > 0) {
ysr@777 2462 gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s",
ysr@777 2463 _all_full_gc_times_ms->num(),
ysr@777 2464 _all_full_gc_times_ms->sum() / 1000.0);
ysr@777 2465 gclog_or_tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times_ms->avg());
ysr@777 2466 gclog_or_tty->print_cr(" [std. dev = %8.2f ms, max = %8.2f ms]",
ysr@777 2467 _all_full_gc_times_ms->sd(),
ysr@777 2468 _all_full_gc_times_ms->maximum());
ysr@777 2469 }
ysr@777 2470 }
ysr@777 2471 }
ysr@777 2472
ysr@777 2473 void G1CollectorPolicy::print_yg_surv_rate_info() const {
ysr@777 2474 #ifndef PRODUCT
ysr@777 2475 _short_lived_surv_rate_group->print_surv_rate_summary();
ysr@777 2476 // add this call for any other surv rate groups
ysr@777 2477 #endif // PRODUCT
ysr@777 2478 }
ysr@777 2479
ysr@777 2480 bool
ysr@777 2481 G1CollectorPolicy::should_add_next_region_to_young_list() {
ysr@777 2482 assert(in_young_gc_mode(), "should be in young GC mode");
ysr@777 2483 bool ret;
ysr@777 2484 size_t young_list_length = _g1->young_list_length();
apetrusenko@980 2485 size_t young_list_max_length = _young_list_target_length;
apetrusenko@980 2486 if (G1FixedEdenSize) {
apetrusenko@980 2487 young_list_max_length -= _max_survivor_regions;
apetrusenko@980 2488 }
apetrusenko@980 2489 if (young_list_length < young_list_max_length) {
ysr@777 2490 ret = true;
ysr@777 2491 ++_region_num_young;
ysr@777 2492 } else {
ysr@777 2493 ret = false;
ysr@777 2494 ++_region_num_tenured;
ysr@777 2495 }
ysr@777 2496
ysr@777 2497 return ret;
ysr@777 2498 }
ysr@777 2499
ysr@777 2500 #ifndef PRODUCT
ysr@777 2501 // for debugging, bit of a hack...
ysr@777 2502 static char*
ysr@777 2503 region_num_to_mbs(int length) {
ysr@777 2504 static char buffer[64];
ysr@777 2505 double bytes = (double) (length * HeapRegion::GrainBytes);
ysr@777 2506 double mbs = bytes / (double) (1024 * 1024);
ysr@777 2507 sprintf(buffer, "%7.2lfMB", mbs);
ysr@777 2508 return buffer;
ysr@777 2509 }
ysr@777 2510 #endif // PRODUCT
ysr@777 2511
ysr@777 2512 void
ysr@777 2513 G1CollectorPolicy::checkpoint_conc_overhead() {
ysr@777 2514 double conc_overhead = 0.0;
ysr@777 2515 if (G1AccountConcurrentOverhead)
ysr@777 2516 conc_overhead = COTracker::totalPredConcOverhead();
ysr@777 2517 _mmu_tracker->update_conc_overhead(conc_overhead);
ysr@777 2518 #if 0
ysr@777 2519 gclog_or_tty->print(" CO %1.4lf TARGET %1.4lf",
ysr@777 2520 conc_overhead, _mmu_tracker->max_gc_time());
ysr@777 2521 #endif
ysr@777 2522 }
ysr@777 2523
ysr@777 2524
apetrusenko@980 2525 size_t G1CollectorPolicy::max_regions(int purpose) {
ysr@777 2526 switch (purpose) {
ysr@777 2527 case GCAllocForSurvived:
apetrusenko@980 2528 return _max_survivor_regions;
ysr@777 2529 case GCAllocForTenured:
apetrusenko@980 2530 return REGIONS_UNLIMITED;
ysr@777 2531 default:
apetrusenko@980 2532 ShouldNotReachHere();
apetrusenko@980 2533 return REGIONS_UNLIMITED;
ysr@777 2534 };
ysr@777 2535 }
ysr@777 2536
apetrusenko@980 2537 // Calculates survivor space parameters.
apetrusenko@980 2538 void G1CollectorPolicy::calculate_survivors_policy()
apetrusenko@980 2539 {
johnc@1186 2540 if (!G1UseSurvivorSpaces) {
apetrusenko@980 2541 return;
apetrusenko@980 2542 }
apetrusenko@980 2543 if (G1FixedSurvivorSpaceSize == 0) {
apetrusenko@980 2544 _max_survivor_regions = _young_list_target_length / SurvivorRatio;
apetrusenko@980 2545 } else {
apetrusenko@982 2546 _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes;
apetrusenko@980 2547 }
apetrusenko@980 2548
apetrusenko@980 2549 if (G1FixedTenuringThreshold) {
apetrusenko@980 2550 _tenuring_threshold = MaxTenuringThreshold;
apetrusenko@980 2551 } else {
apetrusenko@980 2552 _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
apetrusenko@980 2553 HeapRegion::GrainWords * _max_survivor_regions);
apetrusenko@980 2554 }
apetrusenko@980 2555 }
apetrusenko@980 2556
ysr@777 2557 bool
ysr@777 2558 G1CollectorPolicy_BestRegionsFirst::should_do_collection_pause(size_t
ysr@777 2559 word_size) {
ysr@777 2560 assert(_g1->regions_accounted_for(), "Region leakage!");
ysr@777 2561 // Initiate a pause when we reach the steady-state "used" target.
ysr@777 2562 size_t used_hard = (_g1->capacity() / 100) * G1SteadyStateUsed;
ysr@777 2563 size_t used_soft =
ysr@777 2564 MAX2((_g1->capacity() / 100) * (G1SteadyStateUsed - G1SteadyStateUsedDelta),
ysr@777 2565 used_hard/2);
ysr@777 2566 size_t used = _g1->used();
ysr@777 2567
ysr@777 2568 double max_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
ysr@777 2569
ysr@777 2570 size_t young_list_length = _g1->young_list_length();
apetrusenko@980 2571 size_t young_list_max_length = _young_list_target_length;
apetrusenko@980 2572 if (G1FixedEdenSize) {
apetrusenko@980 2573 young_list_max_length -= _max_survivor_regions;
apetrusenko@980 2574 }
apetrusenko@980 2575 bool reached_target_length = young_list_length >= young_list_max_length;
ysr@777 2576
ysr@777 2577 if (in_young_gc_mode()) {
ysr@777 2578 if (reached_target_length) {
ysr@777 2579 assert( young_list_length > 0 && _g1->young_list_length() > 0,
ysr@777 2580 "invariant" );
ysr@777 2581 _target_pause_time_ms = max_pause_time_ms;
ysr@777 2582 return true;
ysr@777 2583 }
ysr@777 2584 } else {
ysr@777 2585 guarantee( false, "should not reach here" );
ysr@777 2586 }
ysr@777 2587
ysr@777 2588 return false;
ysr@777 2589 }
ysr@777 2590
ysr@777 2591 #ifndef PRODUCT
ysr@777 2592 class HRSortIndexIsOKClosure: public HeapRegionClosure {
ysr@777 2593 CollectionSetChooser* _chooser;
ysr@777 2594 public:
ysr@777 2595 HRSortIndexIsOKClosure(CollectionSetChooser* chooser) :
ysr@777 2596 _chooser(chooser) {}
ysr@777 2597
ysr@777 2598 bool doHeapRegion(HeapRegion* r) {
ysr@777 2599 if (!r->continuesHumongous()) {
ysr@777 2600 assert(_chooser->regionProperlyOrdered(r), "Ought to be.");
ysr@777 2601 }
ysr@777 2602 return false;
ysr@777 2603 }
ysr@777 2604 };
ysr@777 2605
ysr@777 2606 bool G1CollectorPolicy_BestRegionsFirst::assertMarkedBytesDataOK() {
ysr@777 2607 HRSortIndexIsOKClosure cl(_collectionSetChooser);
ysr@777 2608 _g1->heap_region_iterate(&cl);
ysr@777 2609 return true;
ysr@777 2610 }
ysr@777 2611 #endif
ysr@777 2612
ysr@777 2613 void
ysr@777 2614 G1CollectorPolicy_BestRegionsFirst::
ysr@777 2615 record_collection_pause_start(double start_time_sec, size_t start_used) {
ysr@777 2616 G1CollectorPolicy::record_collection_pause_start(start_time_sec, start_used);
ysr@777 2617 }
ysr@777 2618
ysr@777 2619 class NextNonCSElemFinder: public HeapRegionClosure {
ysr@777 2620 HeapRegion* _res;
ysr@777 2621 public:
ysr@777 2622 NextNonCSElemFinder(): _res(NULL) {}
ysr@777 2623 bool doHeapRegion(HeapRegion* r) {
ysr@777 2624 if (!r->in_collection_set()) {
ysr@777 2625 _res = r;
ysr@777 2626 return true;
ysr@777 2627 } else {
ysr@777 2628 return false;
ysr@777 2629 }
ysr@777 2630 }
ysr@777 2631 HeapRegion* res() { return _res; }
ysr@777 2632 };
ysr@777 2633
ysr@777 2634 class KnownGarbageClosure: public HeapRegionClosure {
ysr@777 2635 CollectionSetChooser* _hrSorted;
ysr@777 2636
ysr@777 2637 public:
ysr@777 2638 KnownGarbageClosure(CollectionSetChooser* hrSorted) :
ysr@777 2639 _hrSorted(hrSorted)
ysr@777 2640 {}
ysr@777 2641
ysr@777 2642 bool doHeapRegion(HeapRegion* r) {
ysr@777 2643 // We only include humongous regions in collection
ysr@777 2644 // sets when concurrent mark shows that their contained object is
ysr@777 2645 // unreachable.
ysr@777 2646
ysr@777 2647 // Do we have any marking information for this region?
ysr@777 2648 if (r->is_marked()) {
ysr@777 2649 // We don't include humongous regions in collection
ysr@777 2650 // sets because we collect them immediately at the end of a marking
ysr@777 2651 // cycle. We also don't include young regions because we *must*
ysr@777 2652 // include them in the next collection pause.
ysr@777 2653 if (!r->isHumongous() && !r->is_young()) {
ysr@777 2654 _hrSorted->addMarkedHeapRegion(r);
ysr@777 2655 }
ysr@777 2656 }
ysr@777 2657 return false;
ysr@777 2658 }
ysr@777 2659 };
ysr@777 2660
ysr@777 2661 class ParKnownGarbageHRClosure: public HeapRegionClosure {
ysr@777 2662 CollectionSetChooser* _hrSorted;
ysr@777 2663 jint _marked_regions_added;
ysr@777 2664 jint _chunk_size;
ysr@777 2665 jint _cur_chunk_idx;
ysr@777 2666 jint _cur_chunk_end; // Cur chunk [_cur_chunk_idx, _cur_chunk_end)
ysr@777 2667 int _worker;
ysr@777 2668 int _invokes;
ysr@777 2669
ysr@777 2670 void get_new_chunk() {
ysr@777 2671 _cur_chunk_idx = _hrSorted->getParMarkedHeapRegionChunk(_chunk_size);
ysr@777 2672 _cur_chunk_end = _cur_chunk_idx + _chunk_size;
ysr@777 2673 }
ysr@777 2674 void add_region(HeapRegion* r) {
ysr@777 2675 if (_cur_chunk_idx == _cur_chunk_end) {
ysr@777 2676 get_new_chunk();
ysr@777 2677 }
ysr@777 2678 assert(_cur_chunk_idx < _cur_chunk_end, "postcondition");
ysr@777 2679 _hrSorted->setMarkedHeapRegion(_cur_chunk_idx, r);
ysr@777 2680 _marked_regions_added++;
ysr@777 2681 _cur_chunk_idx++;
ysr@777 2682 }
ysr@777 2683
ysr@777 2684 public:
ysr@777 2685 ParKnownGarbageHRClosure(CollectionSetChooser* hrSorted,
ysr@777 2686 jint chunk_size,
ysr@777 2687 int worker) :
ysr@777 2688 _hrSorted(hrSorted), _chunk_size(chunk_size), _worker(worker),
ysr@777 2689 _marked_regions_added(0), _cur_chunk_idx(0), _cur_chunk_end(0),
ysr@777 2690 _invokes(0)
ysr@777 2691 {}
ysr@777 2692
ysr@777 2693 bool doHeapRegion(HeapRegion* r) {
ysr@777 2694 // We only include humongous regions in collection
ysr@777 2695 // sets when concurrent mark shows that their contained object is
ysr@777 2696 // unreachable.
ysr@777 2697 _invokes++;
ysr@777 2698
ysr@777 2699 // Do we have any marking information for this region?
ysr@777 2700 if (r->is_marked()) {
ysr@777 2701 // We don't include humongous regions in collection
ysr@777 2702 // sets because we collect them immediately at the end of a marking
ysr@777 2703 // cycle.
ysr@777 2704 // We also do not include young regions in collection sets
ysr@777 2705 if (!r->isHumongous() && !r->is_young()) {
ysr@777 2706 add_region(r);
ysr@777 2707 }
ysr@777 2708 }
ysr@777 2709 return false;
ysr@777 2710 }
ysr@777 2711 jint marked_regions_added() { return _marked_regions_added; }
ysr@777 2712 int invokes() { return _invokes; }
ysr@777 2713 };
ysr@777 2714
ysr@777 2715 class ParKnownGarbageTask: public AbstractGangTask {
ysr@777 2716 CollectionSetChooser* _hrSorted;
ysr@777 2717 jint _chunk_size;
ysr@777 2718 G1CollectedHeap* _g1;
ysr@777 2719 public:
ysr@777 2720 ParKnownGarbageTask(CollectionSetChooser* hrSorted, jint chunk_size) :
ysr@777 2721 AbstractGangTask("ParKnownGarbageTask"),
ysr@777 2722 _hrSorted(hrSorted), _chunk_size(chunk_size),
ysr@777 2723 _g1(G1CollectedHeap::heap())
ysr@777 2724 {}
ysr@777 2725
ysr@777 2726 void work(int i) {
ysr@777 2727 ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size, i);
ysr@777 2728 // Back to zero for the claim value.
tonyp@790 2729 _g1->heap_region_par_iterate_chunked(&parKnownGarbageCl, i,
tonyp@790 2730 HeapRegion::InitialClaimValue);
ysr@777 2731 jint regions_added = parKnownGarbageCl.marked_regions_added();
ysr@777 2732 _hrSorted->incNumMarkedHeapRegions(regions_added);
ysr@777 2733 if (G1PrintParCleanupStats) {
ysr@777 2734 gclog_or_tty->print(" Thread %d called %d times, added %d regions to list.\n",
ysr@777 2735 i, parKnownGarbageCl.invokes(), regions_added);
ysr@777 2736 }
ysr@777 2737 }
ysr@777 2738 };
ysr@777 2739
ysr@777 2740 void
ysr@777 2741 G1CollectorPolicy_BestRegionsFirst::
ysr@777 2742 record_concurrent_mark_cleanup_end(size_t freed_bytes,
ysr@777 2743 size_t max_live_bytes) {
ysr@777 2744 double start;
ysr@777 2745 if (G1PrintParCleanupStats) start = os::elapsedTime();
ysr@777 2746 record_concurrent_mark_cleanup_end_work1(freed_bytes, max_live_bytes);
ysr@777 2747
ysr@777 2748 _collectionSetChooser->clearMarkedHeapRegions();
ysr@777 2749 double clear_marked_end;
ysr@777 2750 if (G1PrintParCleanupStats) {
ysr@777 2751 clear_marked_end = os::elapsedTime();
ysr@777 2752 gclog_or_tty->print_cr(" clear marked regions + work1: %8.3f ms.",
ysr@777 2753 (clear_marked_end - start)*1000.0);
ysr@777 2754 }
ysr@777 2755 if (ParallelGCThreads > 0) {
ysr@777 2756 const size_t OverpartitionFactor = 4;
ysr@777 2757 const size_t MinChunkSize = 8;
ysr@777 2758 const size_t ChunkSize =
ysr@777 2759 MAX2(_g1->n_regions() / (ParallelGCThreads * OverpartitionFactor),
ysr@777 2760 MinChunkSize);
ysr@777 2761 _collectionSetChooser->prepareForAddMarkedHeapRegionsPar(_g1->n_regions(),
ysr@777 2762 ChunkSize);
ysr@777 2763 ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser,
ysr@777 2764 (int) ChunkSize);
ysr@777 2765 _g1->workers()->run_task(&parKnownGarbageTask);
tonyp@790 2766
tonyp@790 2767 assert(_g1->check_heap_region_claim_values(HeapRegion::InitialClaimValue),
tonyp@790 2768 "sanity check");
ysr@777 2769 } else {
ysr@777 2770 KnownGarbageClosure knownGarbagecl(_collectionSetChooser);
ysr@777 2771 _g1->heap_region_iterate(&knownGarbagecl);
ysr@777 2772 }
ysr@777 2773 double known_garbage_end;
ysr@777 2774 if (G1PrintParCleanupStats) {
ysr@777 2775 known_garbage_end = os::elapsedTime();
ysr@777 2776 gclog_or_tty->print_cr(" compute known garbage: %8.3f ms.",
ysr@777 2777 (known_garbage_end - clear_marked_end)*1000.0);
ysr@777 2778 }
ysr@777 2779 _collectionSetChooser->sortMarkedHeapRegions();
ysr@777 2780 double sort_end;
ysr@777 2781 if (G1PrintParCleanupStats) {
ysr@777 2782 sort_end = os::elapsedTime();
ysr@777 2783 gclog_or_tty->print_cr(" sorting: %8.3f ms.",
ysr@777 2784 (sort_end - known_garbage_end)*1000.0);
ysr@777 2785 }
ysr@777 2786
ysr@777 2787 record_concurrent_mark_cleanup_end_work2();
ysr@777 2788 double work2_end;
ysr@777 2789 if (G1PrintParCleanupStats) {
ysr@777 2790 work2_end = os::elapsedTime();
ysr@777 2791 gclog_or_tty->print_cr(" work2: %8.3f ms.",
ysr@777 2792 (work2_end - sort_end)*1000.0);
ysr@777 2793 }
ysr@777 2794 }
ysr@777 2795
ysr@777 2796 // Add the heap region to the collection set and return the conservative
ysr@777 2797 // estimate of the number of live bytes.
ysr@777 2798 void G1CollectorPolicy::
ysr@777 2799 add_to_collection_set(HeapRegion* hr) {
johnc@1186 2800 if (G1PrintRegions) {
ysr@777 2801 gclog_or_tty->print_cr("added region to cset %d:["PTR_FORMAT", "PTR_FORMAT"], "
ysr@777 2802 "top "PTR_FORMAT", young %s",
ysr@777 2803 hr->hrs_index(), hr->bottom(), hr->end(),
ysr@777 2804 hr->top(), (hr->is_young()) ? "YES" : "NO");
ysr@777 2805 }
ysr@777 2806
ysr@777 2807 if (_g1->mark_in_progress())
ysr@777 2808 _g1->concurrent_mark()->registerCSetRegion(hr);
ysr@777 2809
ysr@777 2810 assert(!hr->in_collection_set(),
ysr@777 2811 "should not already be in the CSet");
ysr@777 2812 hr->set_in_collection_set(true);
ysr@777 2813 hr->set_next_in_collection_set(_collection_set);
ysr@777 2814 _collection_set = hr;
ysr@777 2815 _collection_set_size++;
ysr@777 2816 _collection_set_bytes_used_before += hr->used();
tonyp@961 2817 _g1->register_region_with_in_cset_fast_test(hr);
ysr@777 2818 }
ysr@777 2819
ysr@777 2820 void
ysr@777 2821 G1CollectorPolicy_BestRegionsFirst::
apetrusenko@1112 2822 choose_collection_set() {
ysr@777 2823 double non_young_start_time_sec;
ysr@777 2824 start_recording_regions();
ysr@777 2825
apetrusenko@1112 2826 guarantee(_target_pause_time_ms > -1.0,
apetrusenko@1112 2827 "_target_pause_time_ms should have been set!");
apetrusenko@1112 2828 assert(_collection_set == NULL, "Precondition");
ysr@777 2829
ysr@777 2830 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
ysr@777 2831 double predicted_pause_time_ms = base_time_ms;
ysr@777 2832
ysr@777 2833 double target_time_ms = _target_pause_time_ms;
ysr@777 2834 double time_remaining_ms = target_time_ms - base_time_ms;
ysr@777 2835
ysr@777 2836 // the 10% and 50% values are arbitrary...
ysr@777 2837 if (time_remaining_ms < 0.10*target_time_ms) {
ysr@777 2838 time_remaining_ms = 0.50 * target_time_ms;
ysr@777 2839 _within_target = false;
ysr@777 2840 } else {
ysr@777 2841 _within_target = true;
ysr@777 2842 }
ysr@777 2843
ysr@777 2844 // We figure out the number of bytes available for future to-space.
ysr@777 2845 // For new regions without marking information, we must assume the
ysr@777 2846 // worst-case of complete survival. If we have marking information for a
ysr@777 2847 // region, we can bound the amount of live data. We can add a number of
ysr@777 2848 // such regions, as long as the sum of the live data bounds does not
ysr@777 2849 // exceed the available evacuation space.
ysr@777 2850 size_t max_live_bytes = _g1->free_regions() * HeapRegion::GrainBytes;
ysr@777 2851
ysr@777 2852 size_t expansion_bytes =
ysr@777 2853 _g1->expansion_regions() * HeapRegion::GrainBytes;
ysr@777 2854
apetrusenko@1112 2855 _collection_set_bytes_used_before = 0;
apetrusenko@1112 2856 _collection_set_size = 0;
ysr@777 2857
ysr@777 2858 // Adjust for expansion and slop.
ysr@777 2859 max_live_bytes = max_live_bytes + expansion_bytes;
ysr@777 2860
apetrusenko@1112 2861 assert(_g1->regions_accounted_for(), "Region leakage!");
ysr@777 2862
ysr@777 2863 HeapRegion* hr;
ysr@777 2864 if (in_young_gc_mode()) {
ysr@777 2865 double young_start_time_sec = os::elapsedTime();
ysr@777 2866
ysr@777 2867 if (G1PolicyVerbose > 0) {
ysr@777 2868 gclog_or_tty->print_cr("Adding %d young regions to the CSet",
ysr@777 2869 _g1->young_list_length());
ysr@777 2870 }
ysr@777 2871 _young_cset_length = 0;
ysr@777 2872 _last_young_gc_full = full_young_gcs() ? true : false;
ysr@777 2873 if (_last_young_gc_full)
ysr@777 2874 ++_full_young_pause_num;
ysr@777 2875 else
ysr@777 2876 ++_partial_young_pause_num;
ysr@777 2877 hr = _g1->pop_region_from_young_list();
ysr@777 2878 while (hr != NULL) {
ysr@777 2879
ysr@777 2880 assert( hr->young_index_in_cset() == -1, "invariant" );
ysr@777 2881 assert( hr->age_in_surv_rate_group() != -1, "invariant" );
ysr@777 2882 hr->set_young_index_in_cset((int) _young_cset_length);
ysr@777 2883
ysr@777 2884 ++_young_cset_length;
ysr@777 2885 double predicted_time_ms = predict_region_elapsed_time_ms(hr, true);
ysr@777 2886 time_remaining_ms -= predicted_time_ms;
ysr@777 2887 predicted_pause_time_ms += predicted_time_ms;
apetrusenko@1112 2888 assert(!hr->in_collection_set(), "invariant");
apetrusenko@1112 2889 add_to_collection_set(hr);
apetrusenko@1112 2890 record_cset_region(hr, true);
ysr@777 2891 max_live_bytes -= MIN2(hr->max_live_bytes(), max_live_bytes);
ysr@777 2892 if (G1PolicyVerbose > 0) {
ysr@777 2893 gclog_or_tty->print_cr(" Added [" PTR_FORMAT ", " PTR_FORMAT") to CS.",
ysr@777 2894 hr->bottom(), hr->end());
ysr@777 2895 gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)",
ysr@777 2896 max_live_bytes/K);
ysr@777 2897 }
ysr@777 2898 hr = _g1->pop_region_from_young_list();
ysr@777 2899 }
ysr@777 2900
ysr@777 2901 record_scan_only_regions(_g1->young_list_scan_only_length());
ysr@777 2902
ysr@777 2903 double young_end_time_sec = os::elapsedTime();
ysr@777 2904 _recorded_young_cset_choice_time_ms =
ysr@777 2905 (young_end_time_sec - young_start_time_sec) * 1000.0;
ysr@777 2906
ysr@777 2907 non_young_start_time_sec = os::elapsedTime();
ysr@777 2908
ysr@777 2909 if (_young_cset_length > 0 && _last_young_gc_full) {
ysr@777 2910 // don't bother adding more regions...
ysr@777 2911 goto choose_collection_set_end;
ysr@777 2912 }
ysr@777 2913 }
ysr@777 2914
ysr@777 2915 if (!in_young_gc_mode() || !full_young_gcs()) {
ysr@777 2916 bool should_continue = true;
ysr@777 2917 NumberSeq seq;
ysr@777 2918 double avg_prediction = 100000000000000000.0; // something very large
ysr@777 2919 do {
ysr@777 2920 hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms,
ysr@777 2921 avg_prediction);
apetrusenko@1112 2922 if (hr != NULL) {
ysr@777 2923 double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
ysr@777 2924 time_remaining_ms -= predicted_time_ms;
ysr@777 2925 predicted_pause_time_ms += predicted_time_ms;
ysr@777 2926 add_to_collection_set(hr);
ysr@777 2927 record_cset_region(hr, false);
ysr@777 2928 max_live_bytes -= MIN2(hr->max_live_bytes(), max_live_bytes);
ysr@777 2929 if (G1PolicyVerbose > 0) {
ysr@777 2930 gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)",
ysr@777 2931 max_live_bytes/K);
ysr@777 2932 }
ysr@777 2933 seq.add(predicted_time_ms);
ysr@777 2934 avg_prediction = seq.avg() + seq.sd();
ysr@777 2935 }
ysr@777 2936 should_continue =
ysr@777 2937 ( hr != NULL) &&
ysr@777 2938 ( (adaptive_young_list_length()) ? time_remaining_ms > 0.0
ysr@777 2939 : _collection_set_size < _young_list_fixed_length );
ysr@777 2940 } while (should_continue);
ysr@777 2941
ysr@777 2942 if (!adaptive_young_list_length() &&
ysr@777 2943 _collection_set_size < _young_list_fixed_length)
ysr@777 2944 _should_revert_to_full_young_gcs = true;
ysr@777 2945 }
ysr@777 2946
ysr@777 2947 choose_collection_set_end:
ysr@777 2948 count_CS_bytes_used();
ysr@777 2949
ysr@777 2950 end_recording_regions();
ysr@777 2951
ysr@777 2952 double non_young_end_time_sec = os::elapsedTime();
ysr@777 2953 _recorded_non_young_cset_choice_time_ms =
ysr@777 2954 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0;
ysr@777 2955 }
ysr@777 2956
ysr@777 2957 void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() {
ysr@777 2958 G1CollectorPolicy::record_full_collection_end();
ysr@777 2959 _collectionSetChooser->updateAfterFullCollection();
ysr@777 2960 }
ysr@777 2961
ysr@777 2962 void G1CollectorPolicy_BestRegionsFirst::
ysr@777 2963 expand_if_possible(size_t numRegions) {
ysr@777 2964 size_t expansion_bytes = numRegions * HeapRegion::GrainBytes;
ysr@777 2965 _g1->expand(expansion_bytes);
ysr@777 2966 }
ysr@777 2967
ysr@777 2968 void G1CollectorPolicy_BestRegionsFirst::
apetrusenko@1112 2969 record_collection_pause_end(bool abandoned) {
apetrusenko@1112 2970 G1CollectorPolicy::record_collection_pause_end(abandoned);
ysr@777 2971 assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
ysr@777 2972 }
ysr@777 2973
ysr@777 2974 // Local Variables: ***
ysr@777 2975 // c-indentation-style: gnu ***
ysr@777 2976 // End: ***

mercurial