Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 1394:1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
6871109: G1: remove the concept of the scan only prefix
Summary: Removed scan only regions and associated code. The young portion of the collection set is now constructed incrementally - when a young region is retired as the current allocation region it is added to the collection set.
Reviewed-by: apetrusenko, iveresov, tonyp
author | johnc |
---|---|
date | Thu, 22 Apr 2010 10:02:38 -0700 |
parents | 79e419e5ea3b |
children | c18cbe5936b8 2d127394260e |
comparison
equal
deleted
inserted
replaced
1393:6ecb6e6de3d6 | 1394:1316cec51b4d |
---|---|
1 /* | 1 /* |
2 * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright 2001-2010 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
40 | 40 |
41 static double cost_per_card_ms_defaults[] = { | 41 static double cost_per_card_ms_defaults[] = { |
42 0.01, 0.005, 0.005, 0.003, 0.003, 0.002, 0.002, 0.0015 | 42 0.01, 0.005, 0.005, 0.003, 0.003, 0.002, 0.002, 0.0015 |
43 }; | 43 }; |
44 | 44 |
45 static double cost_per_scan_only_region_ms_defaults[] = { | |
46 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 | |
47 }; | |
48 | |
49 // all the same | 45 // all the same |
50 static double fully_young_cards_per_entry_ratio_defaults[] = { | 46 static double fully_young_cards_per_entry_ratio_defaults[] = { |
51 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 | 47 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 |
52 }; | 48 }; |
53 | 49 |
123 _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 119 _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
124 _prev_collection_pause_end_ms(0.0), | 120 _prev_collection_pause_end_ms(0.0), |
125 _pending_card_diff_seq(new TruncatedSeq(TruncatedSeqLength)), | 121 _pending_card_diff_seq(new TruncatedSeq(TruncatedSeqLength)), |
126 _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)), | 122 _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)), |
127 _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 123 _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
128 _cost_per_scan_only_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | |
129 _fully_young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)), | 124 _fully_young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)), |
130 _partially_young_cards_per_entry_ratio_seq( | 125 _partially_young_cards_per_entry_ratio_seq( |
131 new TruncatedSeq(TruncatedSeqLength)), | 126 new TruncatedSeq(TruncatedSeqLength)), |
132 _cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 127 _cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
133 _partially_young_cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 128 _partially_young_cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
134 _cost_per_byte_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 129 _cost_per_byte_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
135 _cost_per_byte_ms_during_cm_seq(new TruncatedSeq(TruncatedSeqLength)), | 130 _cost_per_byte_ms_during_cm_seq(new TruncatedSeq(TruncatedSeqLength)), |
136 _cost_per_scan_only_region_ms_during_cm_seq(new TruncatedSeq(TruncatedSeqLength)), | |
137 _constant_other_time_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 131 _constant_other_time_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
138 _young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)), | 132 _young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)), |
139 _non_young_other_cost_per_region_ms_seq( | 133 _non_young_other_cost_per_region_ms_seq( |
140 new TruncatedSeq(TruncatedSeqLength)), | 134 new TruncatedSeq(TruncatedSeqLength)), |
141 | 135 |
184 _last_full_young_gc(false), | 178 _last_full_young_gc(false), |
185 | 179 |
186 _prev_collection_pause_used_at_end_bytes(0), | 180 _prev_collection_pause_used_at_end_bytes(0), |
187 | 181 |
188 _collection_set(NULL), | 182 _collection_set(NULL), |
183 _collection_set_size(0), | |
184 _collection_set_bytes_used_before(0), | |
185 | |
186 // Incremental CSet attributes | |
187 _inc_cset_build_state(Inactive), | |
188 _inc_cset_head(NULL), | |
189 _inc_cset_tail(NULL), | |
190 _inc_cset_size(0), | |
191 _inc_cset_young_index(0), | |
192 _inc_cset_bytes_used_before(0), | |
193 _inc_cset_max_finger(NULL), | |
194 _inc_cset_recorded_young_bytes(0), | |
195 _inc_cset_recorded_rs_lengths(0), | |
196 _inc_cset_predicted_elapsed_time_ms(0.0), | |
197 _inc_cset_predicted_bytes_to_copy(0), | |
198 | |
189 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | 199 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away |
190 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | 200 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
191 #endif // _MSC_VER | 201 #endif // _MSC_VER |
192 | 202 |
193 _short_lived_surv_rate_group(new SurvRateGroup(this, "Short Lived", | 203 _short_lived_surv_rate_group(new SurvRateGroup(this, "Short Lived", |
221 _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime()); | 231 _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime()); |
222 _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0; | 232 _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0; |
223 | 233 |
224 _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads]; | 234 _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads]; |
225 _par_last_mark_stack_scan_times_ms = new double[_parallel_gc_threads]; | 235 _par_last_mark_stack_scan_times_ms = new double[_parallel_gc_threads]; |
226 _par_last_scan_only_times_ms = new double[_parallel_gc_threads]; | |
227 _par_last_scan_only_regions_scanned = new double[_parallel_gc_threads]; | |
228 | 236 |
229 _par_last_update_rs_start_times_ms = new double[_parallel_gc_threads]; | 237 _par_last_update_rs_start_times_ms = new double[_parallel_gc_threads]; |
230 _par_last_update_rs_times_ms = new double[_parallel_gc_threads]; | 238 _par_last_update_rs_times_ms = new double[_parallel_gc_threads]; |
231 _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads]; | 239 _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads]; |
232 | 240 |
252 index = ParallelGCThreads - 1; | 260 index = ParallelGCThreads - 1; |
253 | 261 |
254 _pending_card_diff_seq->add(0.0); | 262 _pending_card_diff_seq->add(0.0); |
255 _rs_length_diff_seq->add(rs_length_diff_defaults[index]); | 263 _rs_length_diff_seq->add(rs_length_diff_defaults[index]); |
256 _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]); | 264 _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]); |
257 _cost_per_scan_only_region_ms_seq->add( | |
258 cost_per_scan_only_region_ms_defaults[index]); | |
259 _fully_young_cards_per_entry_ratio_seq->add( | 265 _fully_young_cards_per_entry_ratio_seq->add( |
260 fully_young_cards_per_entry_ratio_defaults[index]); | 266 fully_young_cards_per_entry_ratio_defaults[index]); |
261 _cost_per_entry_ms_seq->add(cost_per_entry_ms_defaults[index]); | 267 _cost_per_entry_ms_seq->add(cost_per_entry_ms_defaults[index]); |
262 _cost_per_byte_ms_seq->add(cost_per_byte_ms_defaults[index]); | 268 _cost_per_byte_ms_seq->add(cost_per_byte_ms_defaults[index]); |
263 _constant_other_time_ms_seq->add(constant_other_time_ms_defaults[index]); | 269 _constant_other_time_ms_seq->add(constant_other_time_ms_defaults[index]); |
281 _concurrent_mark_cleanup_times_ms->add(0.20); | 287 _concurrent_mark_cleanup_times_ms->add(0.20); |
282 _tenuring_threshold = MaxTenuringThreshold; | 288 _tenuring_threshold = MaxTenuringThreshold; |
283 | 289 |
284 // if G1FixedSurvivorSpaceSize is 0 which means the size is not | 290 // if G1FixedSurvivorSpaceSize is 0 which means the size is not |
285 // fixed, then _max_survivor_regions will be calculated at | 291 // fixed, then _max_survivor_regions will be calculated at |
286 // calculate_young_list_target_config during initialization | 292 // calculate_young_list_target_length during initialization |
287 _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes; | 293 _max_survivor_regions = G1FixedSurvivorSpaceSize / HeapRegion::GrainBytes; |
288 | 294 |
289 assert(GCTimeRatio > 0, | 295 assert(GCTimeRatio > 0, |
290 "we should have set it to a default value set_g1_gc_flags() " | 296 "we should have set it to a default value set_g1_gc_flags() " |
291 "if a user set it to 0"); | 297 "if a user set it to 0"); |
355 _young_list_fixed_length = 0; | 361 _young_list_fixed_length = 0; |
356 } else { | 362 } else { |
357 set_adaptive_young_list_length(false); | 363 set_adaptive_young_list_length(false); |
358 _young_list_fixed_length = initial_region_num; | 364 _young_list_fixed_length = initial_region_num; |
359 } | 365 } |
360 _free_regions_at_end_of_collection = _g1->free_regions(); | 366 _free_regions_at_end_of_collection = _g1->free_regions(); |
361 _scan_only_regions_at_end_of_collection = 0; | 367 calculate_young_list_min_length(); |
362 calculate_young_list_min_length(); | 368 guarantee( _young_list_min_length == 0, "invariant, not enough info" ); |
363 guarantee( _young_list_min_length == 0, "invariant, not enough info" ); | 369 calculate_young_list_target_length(); |
364 calculate_young_list_target_config(); | 370 } else { |
365 } else { | |
366 _young_list_fixed_length = 0; | 371 _young_list_fixed_length = 0; |
367 _in_young_gc_mode = false; | 372 _in_young_gc_mode = false; |
368 } | 373 } |
374 | |
375 // We may immediately start allocating regions and placing them on the | |
376 // collection set list. Initialize the per-collection set info | |
377 start_incremental_cset_building(); | |
369 } | 378 } |
370 | 379 |
371 // Create the jstat counters for the policy. | 380 // Create the jstat counters for the policy. |
372 void G1CollectorPolicy::initialize_gc_policy_counters() | 381 void G1CollectorPolicy::initialize_gc_policy_counters() |
373 { | 382 { |
383 if (_alloc_rate_ms_seq->num() > 3) { | 392 if (_alloc_rate_ms_seq->num() > 3) { |
384 double now_sec = os::elapsedTime(); | 393 double now_sec = os::elapsedTime(); |
385 double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; | 394 double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0; |
386 double alloc_rate_ms = predict_alloc_rate_ms(); | 395 double alloc_rate_ms = predict_alloc_rate_ms(); |
387 int min_regions = (int) ceil(alloc_rate_ms * when_ms); | 396 int min_regions = (int) ceil(alloc_rate_ms * when_ms); |
388 int current_region_num = (int) _g1->young_list_length(); | 397 int current_region_num = (int) _g1->young_list()->length(); |
389 _young_list_min_length = min_regions + current_region_num; | 398 _young_list_min_length = min_regions + current_region_num; |
390 } | 399 } |
391 } | 400 } |
392 | 401 |
393 void G1CollectorPolicy::calculate_young_list_target_config() { | 402 void G1CollectorPolicy::calculate_young_list_target_length() { |
394 if (adaptive_young_list_length()) { | 403 if (adaptive_young_list_length()) { |
395 size_t rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq); | 404 size_t rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq); |
396 calculate_young_list_target_config(rs_lengths); | 405 calculate_young_list_target_length(rs_lengths); |
397 } else { | 406 } else { |
398 if (full_young_gcs()) | 407 if (full_young_gcs()) |
399 _young_list_target_length = _young_list_fixed_length; | 408 _young_list_target_length = _young_list_fixed_length; |
400 else | 409 else |
401 _young_list_target_length = _young_list_fixed_length / 2; | 410 _young_list_target_length = _young_list_fixed_length / 2; |
411 | |
402 _young_list_target_length = MAX2(_young_list_target_length, (size_t)1); | 412 _young_list_target_length = MAX2(_young_list_target_length, (size_t)1); |
403 size_t so_length = calculate_optimal_so_length(_young_list_target_length); | |
404 guarantee( so_length < _young_list_target_length, "invariant" ); | |
405 _young_list_so_prefix_length = so_length; | |
406 } | 413 } |
407 calculate_survivors_policy(); | 414 calculate_survivors_policy(); |
408 } | 415 } |
409 | 416 |
410 // This method calculate the optimal scan-only set for a fixed young | 417 void G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths) { |
411 // gen size. I couldn't work out how to reuse the more elaborate one, | |
412 // i.e. calculate_young_list_target_config(rs_length), as the loops are | |
413 // fundamentally different (the other one finds a config for different | |
414 // S-O lengths, whereas here we need to do the opposite). | |
415 size_t G1CollectorPolicy::calculate_optimal_so_length( | |
416 size_t young_list_length) { | |
417 if (!G1UseScanOnlyPrefix) | |
418 return 0; | |
419 | |
420 if (_all_pause_times_ms->num() < 3) { | |
421 // we won't use a scan-only set at the beginning to allow the rest | |
422 // of the predictors to warm up | |
423 return 0; | |
424 } | |
425 | |
426 if (_cost_per_scan_only_region_ms_seq->num() < 3) { | |
427 // then, we'll only set the S-O set to 1 for a little bit of time, | |
428 // to get enough information on the scanning cost | |
429 return 1; | |
430 } | |
431 | |
432 size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq); | |
433 size_t rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq); | |
434 size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff(); | |
435 size_t scanned_cards; | |
436 if (full_young_gcs()) | |
437 scanned_cards = predict_young_card_num(adj_rs_lengths); | |
438 else | |
439 scanned_cards = predict_non_young_card_num(adj_rs_lengths); | |
440 double base_time_ms = predict_base_elapsed_time_ms(pending_cards, | |
441 scanned_cards); | |
442 | |
443 size_t so_length = 0; | |
444 double max_gc_eff = 0.0; | |
445 for (size_t i = 0; i < young_list_length; ++i) { | |
446 double gc_eff = 0.0; | |
447 double pause_time_ms = 0.0; | |
448 predict_gc_eff(young_list_length, i, base_time_ms, | |
449 &gc_eff, &pause_time_ms); | |
450 if (gc_eff > max_gc_eff) { | |
451 max_gc_eff = gc_eff; | |
452 so_length = i; | |
453 } | |
454 } | |
455 | |
456 // set it to 95% of the optimal to make sure we sample the "area" | |
457 // around the optimal length to get up-to-date survival rate data | |
458 return so_length * 950 / 1000; | |
459 } | |
460 | |
461 // This is a really cool piece of code! It finds the best | |
462 // target configuration (young length / scan-only prefix length) so | |
463 // that GC efficiency is maximized and that we also meet a pause | |
464 // time. It's a triple nested loop. These loops are explained below | |
465 // from the inside-out :-) | |
466 // | |
467 // (a) The innermost loop will try to find the optimal young length | |
468 // for a fixed S-O length. It uses a binary search to speed up the | |
469 // process. We assume that, for a fixed S-O length, as we add more | |
470 // young regions to the CSet, the GC efficiency will only go up (I'll | |
471 // skip the proof). So, using a binary search to optimize this process | |
472 // makes perfect sense. | |
473 // | |
474 // (b) The middle loop will fix the S-O length before calling the | |
475 // innermost one. It will vary it between two parameters, increasing | |
476 // it by a given increment. | |
477 // | |
478 // (c) The outermost loop will call the middle loop three times. | |
479 // (1) The first time it will explore all possible S-O length values | |
480 // from 0 to as large as it can get, using a coarse increment (to | |
481 // quickly "home in" to where the optimal seems to be). | |
482 // (2) The second time it will explore the values around the optimal | |
483 // that was found by the first iteration using a fine increment. | |
484 // (3) Once the optimal config has been determined by the second | |
485 // iteration, we'll redo the calculation, but setting the S-O length | |
486 // to 95% of the optimal to make sure we sample the "area" | |
487 // around the optimal length to get up-to-date survival rate data | |
488 // | |
489 // Termination conditions for the iterations are several: the pause | |
490 // time is over the limit, we do not have enough to-space, etc. | |
491 | |
492 void G1CollectorPolicy::calculate_young_list_target_config(size_t rs_lengths) { | |
493 guarantee( adaptive_young_list_length(), "pre-condition" ); | 418 guarantee( adaptive_young_list_length(), "pre-condition" ); |
419 guarantee( !_in_marking_window || !_last_full_young_gc, "invariant" ); | |
494 | 420 |
495 double start_time_sec = os::elapsedTime(); | 421 double start_time_sec = os::elapsedTime(); |
496 size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1ReservePercent); | 422 size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1ReservePercent); |
497 min_reserve_perc = MIN2((size_t) 50, min_reserve_perc); | 423 min_reserve_perc = MIN2((size_t) 50, min_reserve_perc); |
498 size_t reserve_regions = | 424 size_t reserve_regions = |
502 // we are in fully-young mode and there are free regions in the heap | 428 // we are in fully-young mode and there are free regions in the heap |
503 | 429 |
504 double survivor_regions_evac_time = | 430 double survivor_regions_evac_time = |
505 predict_survivor_regions_evac_time(); | 431 predict_survivor_regions_evac_time(); |
506 | 432 |
507 size_t min_so_length = 0; | |
508 size_t max_so_length = 0; | |
509 | |
510 if (G1UseScanOnlyPrefix) { | |
511 if (_all_pause_times_ms->num() < 3) { | |
512 // we won't use a scan-only set at the beginning to allow the rest | |
513 // of the predictors to warm up | |
514 min_so_length = 0; | |
515 max_so_length = 0; | |
516 } else if (_cost_per_scan_only_region_ms_seq->num() < 3) { | |
517 // then, we'll only set the S-O set to 1 for a little bit of time, | |
518 // to get enough information on the scanning cost | |
519 min_so_length = 1; | |
520 max_so_length = 1; | |
521 } else if (_in_marking_window || _last_full_young_gc) { | |
522 // no S-O prefix during a marking phase either, as at the end | |
523 // of the marking phase we'll have to use a very small young | |
524 // length target to fill up the rest of the CSet with | |
525 // non-young regions and, if we have lots of scan-only regions | |
526 // left-over, we will not be able to add any more non-young | |
527 // regions. | |
528 min_so_length = 0; | |
529 max_so_length = 0; | |
530 } else { | |
531 // this is the common case; we'll never reach the maximum, we | |
532 // one of the end conditions will fire well before that | |
533 // (hopefully!) | |
534 min_so_length = 0; | |
535 max_so_length = _free_regions_at_end_of_collection - 1; | |
536 } | |
537 } else { | |
538 // no S-O prefix, as the switch is not set, but we still need to | |
539 // do one iteration to calculate the best young target that | |
540 // meets the pause time; this way we reuse the same code instead | |
541 // of replicating it | |
542 min_so_length = 0; | |
543 max_so_length = 0; | |
544 } | |
545 | |
546 double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; | 433 double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; |
547 size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq); | 434 size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq); |
548 size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff(); | 435 size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff(); |
549 size_t scanned_cards; | 436 size_t scanned_cards = predict_young_card_num(adj_rs_lengths); |
550 if (full_young_gcs()) | |
551 scanned_cards = predict_young_card_num(adj_rs_lengths); | |
552 else | |
553 scanned_cards = predict_non_young_card_num(adj_rs_lengths); | |
554 // calculate this once, so that we don't have to recalculate it in | |
555 // the innermost loop | |
556 double base_time_ms = predict_base_elapsed_time_ms(pending_cards, scanned_cards) | 437 double base_time_ms = predict_base_elapsed_time_ms(pending_cards, scanned_cards) |
557 + survivor_regions_evac_time; | 438 + survivor_regions_evac_time; |
439 | |
558 // the result | 440 // the result |
559 size_t final_young_length = 0; | 441 size_t final_young_length = 0; |
560 size_t final_so_length = 0; | 442 |
561 double final_gc_eff = 0.0; | 443 size_t init_free_regions = |
562 // we'll also keep track of how many times we go into the inner loop | 444 MAX2((size_t)0, _free_regions_at_end_of_collection - reserve_regions); |
563 // this is for profiling reasons | 445 |
564 size_t calculations = 0; | 446 // if we're still under the pause target... |
565 | 447 if (base_time_ms <= target_pause_time_ms) { |
566 // this determines which of the three iterations the outer loop is in | 448 // We make sure that the shortest young length that makes sense |
567 typedef enum { | 449 // fits within the target pause time. |
568 pass_type_coarse, | 450 size_t min_young_length = 1; |
569 pass_type_fine, | 451 |
570 pass_type_final | 452 if (predict_will_fit(min_young_length, base_time_ms, |
571 } pass_type_t; | 453 init_free_regions, target_pause_time_ms)) { |
572 | 454 // The shortest young length will fit within the target pause time; |
573 // range of the outer loop's iteration | 455 // we'll now check whether the absolute maximum number of young |
574 size_t from_so_length = min_so_length; | 456 // regions will fit in the target pause time. If not, we'll do |
575 size_t to_so_length = max_so_length; | 457 // a binary search between min_young_length and max_young_length |
576 guarantee( from_so_length <= to_so_length, "invariant" ); | 458 size_t abs_max_young_length = _free_regions_at_end_of_collection - 1; |
577 | 459 size_t max_young_length = abs_max_young_length; |
578 // this will keep the S-O length that's found by the second | 460 |
579 // iteration of the outer loop; we'll keep it just in case the third | 461 if (max_young_length > min_young_length) { |
580 // iteration fails to find something | 462 // Let's check if the initial max young length will fit within the |
581 size_t fine_so_length = 0; | 463 // target pause. If so then there is no need to search for a maximal |
582 | 464 // young length - we'll return the initial maximum |
583 // the increment step for the coarse (first) iteration | 465 |
584 size_t so_coarse_increments = 5; | 466 if (predict_will_fit(max_young_length, base_time_ms, |
585 | 467 init_free_regions, target_pause_time_ms)) { |
586 // the common case, we'll start with the coarse iteration | 468 // The maximum young length will satisfy the target pause time. |
587 pass_type_t pass = pass_type_coarse; | 469 // We are done so set min young length to this maximum length. |
588 size_t so_length_incr = so_coarse_increments; | 470 // The code after the loop will then set final_young_length using |
589 | 471 // the value cached in the minimum length. |
590 if (from_so_length == to_so_length) { | 472 min_young_length = max_young_length; |
591 // not point in doing the coarse iteration, we'll go directly into | 473 } else { |
592 // the fine one (we essentially trying to find the optimal young | 474 // The maximum possible number of young regions will not fit within |
593 // length for a fixed S-O length). | 475 // the target pause time so let's search.... |
594 so_length_incr = 1; | |
595 pass = pass_type_final; | |
596 } else if (to_so_length - from_so_length < 3 * so_coarse_increments) { | |
597 // again, the range is too short so no point in foind the coarse | |
598 // iteration either | |
599 so_length_incr = 1; | |
600 pass = pass_type_fine; | |
601 } | |
602 | |
603 bool done = false; | |
604 // this is the outermost loop | |
605 while (!done) { | |
606 #ifdef TRACE_CALC_YOUNG_CONFIG | |
607 // leave this in for debugging, just in case | |
608 gclog_or_tty->print_cr("searching between " SIZE_FORMAT " and " SIZE_FORMAT | |
609 ", incr " SIZE_FORMAT ", pass %s", | |
610 from_so_length, to_so_length, so_length_incr, | |
611 (pass == pass_type_coarse) ? "coarse" : | |
612 (pass == pass_type_fine) ? "fine" : "final"); | |
613 #endif // TRACE_CALC_YOUNG_CONFIG | |
614 | |
615 size_t so_length = from_so_length; | |
616 size_t init_free_regions = | |
617 MAX2((size_t)0, | |
618 _free_regions_at_end_of_collection + | |
619 _scan_only_regions_at_end_of_collection - reserve_regions); | |
620 | |
621 // this determines whether a configuration was found | |
622 bool gc_eff_set = false; | |
623 // this is the middle loop | |
624 while (so_length <= to_so_length) { | |
625 // base time, which excludes region-related time; again we | |
626 // calculate it once to avoid recalculating it in the | |
627 // innermost loop | |
628 double base_time_with_so_ms = | |
629 base_time_ms + predict_scan_only_time_ms(so_length); | |
630 // it's already over the pause target, go around | |
631 if (base_time_with_so_ms > target_pause_time_ms) | |
632 break; | |
633 | |
634 size_t starting_young_length = so_length+1; | |
635 | |
636 // we make sure that the short young length that makes sense | |
637 // (one more than the S-O length) is feasible | |
638 size_t min_young_length = starting_young_length; | |
639 double min_gc_eff; | |
640 bool min_ok; | |
641 ++calculations; | |
642 min_ok = predict_gc_eff(min_young_length, so_length, | |
643 base_time_with_so_ms, | |
644 init_free_regions, target_pause_time_ms, | |
645 &min_gc_eff); | |
646 | |
647 if (min_ok) { | |
648 // the shortest young length is indeed feasible; we'll know | |
649 // set up the max young length and we'll do a binary search | |
650 // between min_young_length and max_young_length | |
651 size_t max_young_length = _free_regions_at_end_of_collection - 1; | |
652 double max_gc_eff = 0.0; | |
653 bool max_ok = false; | |
654 | |
655 // the innermost loop! (finally!) | |
656 while (max_young_length > min_young_length) { | |
657 // we'll make sure that min_young_length is always at a | |
658 // feasible config | |
659 guarantee( min_ok, "invariant" ); | |
660 | |
661 ++calculations; | |
662 max_ok = predict_gc_eff(max_young_length, so_length, | |
663 base_time_with_so_ms, | |
664 init_free_regions, target_pause_time_ms, | |
665 &max_gc_eff); | |
666 | 476 |
667 size_t diff = (max_young_length - min_young_length) / 2; | 477 size_t diff = (max_young_length - min_young_length) / 2; |
668 if (max_ok) { | 478 max_young_length = min_young_length + diff; |
669 min_young_length = max_young_length; | 479 |
670 min_gc_eff = max_gc_eff; | 480 while (max_young_length > min_young_length) { |
671 min_ok = true; | 481 if (predict_will_fit(max_young_length, base_time_ms, |
482 init_free_regions, target_pause_time_ms)) { | |
483 | |
484 // The current max young length will fit within the target | |
485 // pause time. Note we do not exit the loop here. By setting | |
486 // min = max, and then increasing the max below means that | |
487 // we will continue searching for an upper bound in the | |
488 // range [max..max+diff] | |
489 min_young_length = max_young_length; | |
490 } | |
491 diff = (max_young_length - min_young_length) / 2; | |
492 max_young_length = min_young_length + diff; | |
672 } | 493 } |
673 max_young_length = min_young_length + diff; | 494 // the above loop found a maximal young length that will fit |
495 // within the target pause time. | |
674 } | 496 } |
675 | 497 assert(min_young_length <= abs_max_young_length, "just checking"); |
676 // the innermost loop found a config | |
677 guarantee( min_ok, "invariant" ); | |
678 if (min_gc_eff > final_gc_eff) { | |
679 // it's the best config so far, so we'll keep it | |
680 final_gc_eff = min_gc_eff; | |
681 final_young_length = min_young_length; | |
682 final_so_length = so_length; | |
683 gc_eff_set = true; | |
684 } | |
685 } | 498 } |
686 | 499 final_young_length = min_young_length; |
687 // incremental the fixed S-O length and go around | |
688 so_length += so_length_incr; | |
689 } | 500 } |
690 | 501 } |
691 // this is the end of the outermost loop and we need to decide | 502 // and we're done! |
692 // what to do during the next iteration | |
693 if (pass == pass_type_coarse) { | |
694 // we just did the coarse pass (first iteration) | |
695 | |
696 if (!gc_eff_set) | |
697 // we didn't find a feasible config so we'll just bail out; of | |
698 // course, it might be the case that we missed it; but I'd say | |
699 // it's a bit unlikely | |
700 done = true; | |
701 else { | |
702 // We did find a feasible config with optimal GC eff during | |
703 // the first pass. So the second pass we'll only consider the | |
704 // S-O lengths around that config with a fine increment. | |
705 | |
706 guarantee( so_length_incr == so_coarse_increments, "invariant" ); | |
707 guarantee( final_so_length >= min_so_length, "invariant" ); | |
708 | |
709 #ifdef TRACE_CALC_YOUNG_CONFIG | |
710 // leave this in for debugging, just in case | |
711 gclog_or_tty->print_cr(" coarse pass: SO length " SIZE_FORMAT, | |
712 final_so_length); | |
713 #endif // TRACE_CALC_YOUNG_CONFIG | |
714 | |
715 from_so_length = | |
716 (final_so_length - min_so_length > so_coarse_increments) ? | |
717 final_so_length - so_coarse_increments + 1 : min_so_length; | |
718 to_so_length = | |
719 (max_so_length - final_so_length > so_coarse_increments) ? | |
720 final_so_length + so_coarse_increments - 1 : max_so_length; | |
721 | |
722 pass = pass_type_fine; | |
723 so_length_incr = 1; | |
724 } | |
725 } else if (pass == pass_type_fine) { | |
726 // we just finished the second pass | |
727 | |
728 if (!gc_eff_set) { | |
729 // we didn't find a feasible config (yes, it's possible; | |
730 // notice that, sometimes, we go directly into the fine | |
731 // iteration and skip the coarse one) so we bail out | |
732 done = true; | |
733 } else { | |
734 // We did find a feasible config with optimal GC eff | |
735 guarantee( so_length_incr == 1, "invariant" ); | |
736 | |
737 if (final_so_length == 0) { | |
738 // The config is of an empty S-O set, so we'll just bail out | |
739 done = true; | |
740 } else { | |
741 // we'll go around once more, setting the S-O length to 95% | |
742 // of the optimal | |
743 size_t new_so_length = 950 * final_so_length / 1000; | |
744 | |
745 #ifdef TRACE_CALC_YOUNG_CONFIG | |
746 // leave this in for debugging, just in case | |
747 gclog_or_tty->print_cr(" fine pass: SO length " SIZE_FORMAT | |
748 ", setting it to " SIZE_FORMAT, | |
749 final_so_length, new_so_length); | |
750 #endif // TRACE_CALC_YOUNG_CONFIG | |
751 | |
752 from_so_length = new_so_length; | |
753 to_so_length = new_so_length; | |
754 fine_so_length = final_so_length; | |
755 | |
756 pass = pass_type_final; | |
757 } | |
758 } | |
759 } else if (pass == pass_type_final) { | |
760 // we just finished the final (third) pass | |
761 | |
762 if (!gc_eff_set) | |
763 // we didn't find a feasible config, so we'll just use the one | |
764 // we found during the second pass, which we saved | |
765 final_so_length = fine_so_length; | |
766 | |
767 // and we're done! | |
768 done = true; | |
769 } else { | |
770 guarantee( false, "should never reach here" ); | |
771 } | |
772 | |
773 // we now go around the outermost loop | |
774 } | |
775 | 503 |
776 // we should have at least one region in the target young length | 504 // we should have at least one region in the target young length |
777 _young_list_target_length = | 505 _young_list_target_length = |
778 MAX2((size_t) 1, final_young_length + _recorded_survivor_regions); | 506 MAX2((size_t) 1, final_young_length + _recorded_survivor_regions); |
779 if (final_so_length >= final_young_length) | |
780 // and we need to ensure that the S-O length is not greater than | |
781 // the target young length (this is being a bit careful) | |
782 final_so_length = 0; | |
783 _young_list_so_prefix_length = final_so_length; | |
784 guarantee( !_in_marking_window || !_last_full_young_gc || | |
785 _young_list_so_prefix_length == 0, "invariant" ); | |
786 | 507 |
787 // let's keep an eye of how long we spend on this calculation | 508 // let's keep an eye of how long we spend on this calculation |
788 // right now, I assume that we'll print it when we need it; we | 509 // right now, I assume that we'll print it when we need it; we |
789 // should really adde it to the breakdown of a pause | 510 // should really adde it to the breakdown of a pause |
790 double end_time_sec = os::elapsedTime(); | 511 double end_time_sec = os::elapsedTime(); |
791 double elapsed_time_ms = (end_time_sec - start_time_sec) * 1000.0; | 512 double elapsed_time_ms = (end_time_sec - start_time_sec) * 1000.0; |
792 | 513 |
793 #ifdef TRACE_CALC_YOUNG_CONFIG | 514 #ifdef TRACE_CALC_YOUNG_LENGTH |
794 // leave this in for debugging, just in case | 515 // leave this in for debugging, just in case |
795 gclog_or_tty->print_cr("target = %1.1lf ms, young = " SIZE_FORMAT | 516 gclog_or_tty->print_cr("target = %1.1lf ms, young = " SIZE_FORMAT ", " |
796 ", SO = " SIZE_FORMAT ", " | 517 "elapsed %1.2lf ms, (%s%s) " SIZE_FORMAT SIZE_FORMAT, |
797 "elapsed %1.2lf ms, calcs: " SIZE_FORMAT " (%s%s) " | |
798 SIZE_FORMAT SIZE_FORMAT, | |
799 target_pause_time_ms, | 518 target_pause_time_ms, |
800 _young_list_target_length - _young_list_so_prefix_length, | 519 _young_list_target_length |
801 _young_list_so_prefix_length, | |
802 elapsed_time_ms, | 520 elapsed_time_ms, |
803 calculations, | |
804 full_young_gcs() ? "full" : "partial", | 521 full_young_gcs() ? "full" : "partial", |
805 during_initial_mark_pause() ? " i-m" : "", | 522 during_initial_mark_pause() ? " i-m" : "", |
806 _in_marking_window, | 523 _in_marking_window, |
807 _in_marking_window_im); | 524 _in_marking_window_im); |
808 #endif // TRACE_CALC_YOUNG_CONFIG | 525 #endif // TRACE_CALC_YOUNG_LENGTH |
809 | 526 |
810 if (_young_list_target_length < _young_list_min_length) { | 527 if (_young_list_target_length < _young_list_min_length) { |
811 // bummer; this means that, if we do a pause when the optimal | 528 // bummer; this means that, if we do a pause when the maximal |
812 // config dictates, we'll violate the pause spacing target (the | 529 // length dictates, we'll violate the pause spacing target (the |
813 // min length was calculate based on the application's current | 530 // min length was calculate based on the application's current |
814 // alloc rate); | 531 // alloc rate); |
815 | 532 |
816 // so, we have to bite the bullet, and allocate the minimum | 533 // so, we have to bite the bullet, and allocate the minimum |
817 // number. We'll violate our target, but we just can't meet it. | 534 // number. We'll violate our target, but we just can't meet it. |
818 | 535 |
819 size_t so_length = 0; | 536 #ifdef TRACE_CALC_YOUNG_LENGTH |
820 // a note further up explains why we do not want an S-O length | |
821 // during marking | |
822 if (!_in_marking_window && !_last_full_young_gc) | |
823 // but we can still try to see whether we can find an optimal | |
824 // S-O length | |
825 so_length = calculate_optimal_so_length(_young_list_min_length); | |
826 | |
827 #ifdef TRACE_CALC_YOUNG_CONFIG | |
828 // leave this in for debugging, just in case | 537 // leave this in for debugging, just in case |
829 gclog_or_tty->print_cr("adjusted target length from " | 538 gclog_or_tty->print_cr("adjusted target length from " |
830 SIZE_FORMAT " to " SIZE_FORMAT | 539 SIZE_FORMAT " to " SIZE_FORMAT, |
831 ", SO " SIZE_FORMAT, | 540 _young_list_target_length, _young_list_min_length); |
832 _young_list_target_length, _young_list_min_length, | 541 #endif // TRACE_CALC_YOUNG_LENGTH |
833 so_length); | 542 |
834 #endif // TRACE_CALC_YOUNG_CONFIG | 543 _young_list_target_length = _young_list_min_length; |
835 | |
836 _young_list_target_length = | |
837 MAX2(_young_list_min_length, (size_t)1); | |
838 _young_list_so_prefix_length = so_length; | |
839 } | 544 } |
840 } else { | 545 } else { |
841 // we are in a partially-young mode or we've run out of regions (due | 546 // we are in a partially-young mode or we've run out of regions (due |
842 // to evacuation failure) | 547 // to evacuation failure) |
843 | 548 |
844 #ifdef TRACE_CALC_YOUNG_CONFIG | 549 #ifdef TRACE_CALC_YOUNG_LENGTH |
845 // leave this in for debugging, just in case | 550 // leave this in for debugging, just in case |
846 gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT | 551 gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT |
847 ", SO " SIZE_FORMAT, | 552 _young_list_min_length); |
848 _young_list_min_length, 0); | 553 #endif // TRACE_CALC_YOUNG_LENGTH |
849 #endif // TRACE_CALC_YOUNG_CONFIG | 554 // we'll do the pause as soon as possible by choosing the minimum |
850 | |
851 // we'll do the pause as soon as possible and with no S-O prefix | |
852 // (see above for the reasons behind the latter) | |
853 _young_list_target_length = | 555 _young_list_target_length = |
854 MAX2(_young_list_min_length, (size_t) 1); | 556 MAX2(_young_list_min_length, (size_t) 1); |
855 _young_list_so_prefix_length = 0; | |
856 } | 557 } |
857 | 558 |
858 _rs_lengths_prediction = rs_lengths; | 559 _rs_lengths_prediction = rs_lengths; |
859 } | 560 } |
860 | 561 |
861 // This is used by: calculate_optimal_so_length(length). It returns | 562 // This is used by: calculate_young_list_target_length(rs_length). It |
862 // the GC eff and predicted pause time for a particular config | 563 // returns true iff: |
863 void | 564 // the predicted pause time for the given young list will not overflow |
864 G1CollectorPolicy::predict_gc_eff(size_t young_length, | 565 // the target pause time |
865 size_t so_length, | 566 // and: |
866 double base_time_ms, | 567 // the predicted amount of surviving data will not overflow the |
867 double* ret_gc_eff, | 568 // the amount of free space available for survivor regions. |
868 double* ret_pause_time_ms) { | 569 // |
869 double so_time_ms = predict_scan_only_time_ms(so_length); | |
870 double accum_surv_rate_adj = 0.0; | |
871 if (so_length > 0) | |
872 accum_surv_rate_adj = accum_yg_surv_rate_pred((int)(so_length - 1)); | |
873 double accum_surv_rate = | |
874 accum_yg_surv_rate_pred((int)(young_length - 1)) - accum_surv_rate_adj; | |
875 size_t bytes_to_copy = | |
876 (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes); | |
877 double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy); | |
878 double young_other_time_ms = | |
879 predict_young_other_time_ms(young_length - so_length); | |
880 double pause_time_ms = | |
881 base_time_ms + so_time_ms + copy_time_ms + young_other_time_ms; | |
882 size_t reclaimed_bytes = | |
883 (young_length - so_length) * HeapRegion::GrainBytes - bytes_to_copy; | |
884 double gc_eff = (double) reclaimed_bytes / pause_time_ms; | |
885 | |
886 *ret_gc_eff = gc_eff; | |
887 *ret_pause_time_ms = pause_time_ms; | |
888 } | |
889 | |
890 // This is used by: calculate_young_list_target_config(rs_length). It | |
891 // returns the GC eff of a particular config. It returns false if that | |
892 // config violates any of the end conditions of the search in the | |
893 // calling method, or true upon success. The end conditions were put | |
894 // here since it's called twice and it was best not to replicate them | |
895 // in the caller. Also, passing the parameteres avoids having to | |
896 // recalculate them in the innermost loop. | |
897 bool | 570 bool |
898 G1CollectorPolicy::predict_gc_eff(size_t young_length, | 571 G1CollectorPolicy::predict_will_fit(size_t young_length, |
899 size_t so_length, | 572 double base_time_ms, |
900 double base_time_with_so_ms, | 573 size_t init_free_regions, |
901 size_t init_free_regions, | 574 double target_pause_time_ms) { |
902 double target_pause_time_ms, | |
903 double* ret_gc_eff) { | |
904 *ret_gc_eff = 0.0; | |
905 | 575 |
906 if (young_length >= init_free_regions) | 576 if (young_length >= init_free_regions) |
907 // end condition 1: not enough space for the young regions | 577 // end condition 1: not enough space for the young regions |
908 return false; | 578 return false; |
909 | 579 |
910 double accum_surv_rate_adj = 0.0; | 580 double accum_surv_rate_adj = 0.0; |
911 if (so_length > 0) | |
912 accum_surv_rate_adj = accum_yg_surv_rate_pred((int)(so_length - 1)); | |
913 double accum_surv_rate = | 581 double accum_surv_rate = |
914 accum_yg_surv_rate_pred((int)(young_length - 1)) - accum_surv_rate_adj; | 582 accum_yg_surv_rate_pred((int)(young_length - 1)) - accum_surv_rate_adj; |
583 | |
915 size_t bytes_to_copy = | 584 size_t bytes_to_copy = |
916 (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes); | 585 (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes); |
586 | |
917 double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy); | 587 double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy); |
588 | |
918 double young_other_time_ms = | 589 double young_other_time_ms = |
919 predict_young_other_time_ms(young_length - so_length); | 590 predict_young_other_time_ms(young_length); |
591 | |
920 double pause_time_ms = | 592 double pause_time_ms = |
921 base_time_with_so_ms + copy_time_ms + young_other_time_ms; | 593 base_time_ms + copy_time_ms + young_other_time_ms; |
922 | 594 |
923 if (pause_time_ms > target_pause_time_ms) | 595 if (pause_time_ms > target_pause_time_ms) |
924 // end condition 2: over the target pause time | 596 // end condition 2: over the target pause time |
925 return false; | 597 return false; |
926 | 598 |
927 size_t reclaimed_bytes = | |
928 (young_length - so_length) * HeapRegion::GrainBytes - bytes_to_copy; | |
929 size_t free_bytes = | 599 size_t free_bytes = |
930 (init_free_regions - young_length) * HeapRegion::GrainBytes; | 600 (init_free_regions - young_length) * HeapRegion::GrainBytes; |
931 | 601 |
932 if ((2.0 + sigma()) * (double) bytes_to_copy > (double) free_bytes) | 602 if ((2.0 + sigma()) * (double) bytes_to_copy > (double) free_bytes) |
933 // end condition 3: out of to-space (conservatively) | 603 // end condition 3: out of to-space (conservatively) |
934 return false; | 604 return false; |
935 | 605 |
936 // success! | 606 // success! |
937 double gc_eff = (double) reclaimed_bytes / pause_time_ms; | |
938 *ret_gc_eff = gc_eff; | |
939 | |
940 return true; | 607 return true; |
941 } | 608 } |
942 | 609 |
943 double G1CollectorPolicy::predict_survivor_regions_evac_time() { | 610 double G1CollectorPolicy::predict_survivor_regions_evac_time() { |
944 double survivor_regions_evac_time = 0.0; | 611 double survivor_regions_evac_time = 0.0; |
951 } | 618 } |
952 | 619 |
953 void G1CollectorPolicy::check_prediction_validity() { | 620 void G1CollectorPolicy::check_prediction_validity() { |
954 guarantee( adaptive_young_list_length(), "should not call this otherwise" ); | 621 guarantee( adaptive_young_list_length(), "should not call this otherwise" ); |
955 | 622 |
956 size_t rs_lengths = _g1->young_list_sampled_rs_lengths(); | 623 size_t rs_lengths = _g1->young_list()->sampled_rs_lengths(); |
957 if (rs_lengths > _rs_lengths_prediction) { | 624 if (rs_lengths > _rs_lengths_prediction) { |
958 // add 10% to avoid having to recalculate often | 625 // add 10% to avoid having to recalculate often |
959 size_t rs_lengths_prediction = rs_lengths * 1100 / 1000; | 626 size_t rs_lengths_prediction = rs_lengths * 1100 / 1000; |
960 calculate_young_list_target_config(rs_lengths_prediction); | 627 calculate_young_list_target_length(rs_lengths_prediction); |
961 } | 628 } |
962 } | 629 } |
963 | 630 |
964 HeapWord* G1CollectorPolicy::mem_allocate_work(size_t size, | 631 HeapWord* G1CollectorPolicy::mem_allocate_work(size_t size, |
965 bool is_tlab, | 632 bool is_tlab, |
977 } | 644 } |
978 | 645 |
979 | 646 |
980 #ifndef PRODUCT | 647 #ifndef PRODUCT |
981 bool G1CollectorPolicy::verify_young_ages() { | 648 bool G1CollectorPolicy::verify_young_ages() { |
982 HeapRegion* head = _g1->young_list_first_region(); | 649 HeapRegion* head = _g1->young_list()->first_region(); |
983 return | 650 return |
984 verify_young_ages(head, _short_lived_surv_rate_group); | 651 verify_young_ages(head, _short_lived_surv_rate_group); |
985 // also call verify_young_ages on any additional surv rate groups | 652 // also call verify_young_ages on any additional surv rate groups |
986 } | 653 } |
987 | 654 |
1054 _known_garbage_bytes = 0; | 721 _known_garbage_bytes = 0; |
1055 _known_garbage_ratio = 0.0; | 722 _known_garbage_ratio = 0.0; |
1056 _in_marking_window = false; | 723 _in_marking_window = false; |
1057 _in_marking_window_im = false; | 724 _in_marking_window_im = false; |
1058 | 725 |
1059 _short_lived_surv_rate_group->record_scan_only_prefix(0); | |
1060 _short_lived_surv_rate_group->start_adding_regions(); | 726 _short_lived_surv_rate_group->start_adding_regions(); |
1061 // also call this on any additional surv rate groups | 727 // also call this on any additional surv rate groups |
1062 | 728 |
1063 record_survivor_regions(0, NULL, NULL); | 729 record_survivor_regions(0, NULL, NULL); |
1064 | 730 |
1065 _prev_region_num_young = _region_num_young; | 731 _prev_region_num_young = _region_num_young; |
1066 _prev_region_num_tenured = _region_num_tenured; | 732 _prev_region_num_tenured = _region_num_tenured; |
1067 | 733 |
1068 _free_regions_at_end_of_collection = _g1->free_regions(); | 734 _free_regions_at_end_of_collection = _g1->free_regions(); |
1069 _scan_only_regions_at_end_of_collection = 0; | |
1070 // Reset survivors SurvRateGroup. | 735 // Reset survivors SurvRateGroup. |
1071 _survivor_surv_rate_group->reset(); | 736 _survivor_surv_rate_group->reset(); |
1072 calculate_young_list_min_length(); | 737 calculate_young_list_min_length(); |
1073 calculate_young_list_target_config(); | 738 calculate_young_list_target_length(); |
1074 } | 739 } |
1075 | 740 |
1076 void G1CollectorPolicy::record_before_bytes(size_t bytes) { | 741 void G1CollectorPolicy::record_before_bytes(size_t bytes) { |
1077 _bytes_in_to_space_before_gc += bytes; | 742 _bytes_in_to_space_before_gc += bytes; |
1078 } | 743 } |
1117 // if they are not set properly | 782 // if they are not set properly |
1118 | 783 |
1119 for (int i = 0; i < _parallel_gc_threads; ++i) { | 784 for (int i = 0; i < _parallel_gc_threads; ++i) { |
1120 _par_last_ext_root_scan_times_ms[i] = -666.0; | 785 _par_last_ext_root_scan_times_ms[i] = -666.0; |
1121 _par_last_mark_stack_scan_times_ms[i] = -666.0; | 786 _par_last_mark_stack_scan_times_ms[i] = -666.0; |
1122 _par_last_scan_only_times_ms[i] = -666.0; | |
1123 _par_last_scan_only_regions_scanned[i] = -666.0; | |
1124 _par_last_update_rs_start_times_ms[i] = -666.0; | 787 _par_last_update_rs_start_times_ms[i] = -666.0; |
1125 _par_last_update_rs_times_ms[i] = -666.0; | 788 _par_last_update_rs_times_ms[i] = -666.0; |
1126 _par_last_update_rs_processed_buffers[i] = -666.0; | 789 _par_last_update_rs_processed_buffers[i] = -666.0; |
1127 _par_last_scan_rs_start_times_ms[i] = -666.0; | 790 _par_last_scan_rs_start_times_ms[i] = -666.0; |
1128 _par_last_scan_rs_times_ms[i] = -666.0; | 791 _par_last_scan_rs_times_ms[i] = -666.0; |
1141 _last_satb_drain_processed_buffers = -1; | 804 _last_satb_drain_processed_buffers = -1; |
1142 | 805 |
1143 if (in_young_gc_mode()) | 806 if (in_young_gc_mode()) |
1144 _last_young_gc_full = false; | 807 _last_young_gc_full = false; |
1145 | 808 |
1146 | |
1147 // do that for any other surv rate groups | 809 // do that for any other surv rate groups |
1148 _short_lived_surv_rate_group->stop_adding_regions(); | 810 _short_lived_surv_rate_group->stop_adding_regions(); |
1149 size_t short_lived_so_length = _young_list_so_prefix_length; | |
1150 _short_lived_surv_rate_group->record_scan_only_prefix(short_lived_so_length); | |
1151 tag_scan_only(short_lived_so_length); | |
1152 _survivors_age_table.clear(); | 811 _survivors_age_table.clear(); |
1153 | 812 |
1154 assert( verify_young_ages(), "region age verification" ); | 813 assert( verify_young_ages(), "region age verification" ); |
1155 } | |
1156 | |
1157 void G1CollectorPolicy::tag_scan_only(size_t short_lived_scan_only_length) { | |
1158 // done in a way that it can be extended for other surv rate groups too... | |
1159 | |
1160 HeapRegion* head = _g1->young_list_first_region(); | |
1161 bool finished_short_lived = (short_lived_scan_only_length == 0); | |
1162 | |
1163 if (finished_short_lived) | |
1164 return; | |
1165 | |
1166 for (HeapRegion* curr = head; | |
1167 curr != NULL; | |
1168 curr = curr->get_next_young_region()) { | |
1169 SurvRateGroup* surv_rate_group = curr->surv_rate_group(); | |
1170 int age = curr->age_in_surv_rate_group(); | |
1171 | |
1172 if (surv_rate_group == _short_lived_surv_rate_group) { | |
1173 if ((size_t)age < short_lived_scan_only_length) | |
1174 curr->set_scan_only(); | |
1175 else | |
1176 finished_short_lived = true; | |
1177 } | |
1178 | |
1179 | |
1180 if (finished_short_lived) | |
1181 return; | |
1182 } | |
1183 | |
1184 guarantee( false, "we should never reach here" ); | |
1185 } | 814 } |
1186 | 815 |
1187 void G1CollectorPolicy::record_mark_closure_time(double mark_closure_time_ms) { | 816 void G1CollectorPolicy::record_mark_closure_time(double mark_closure_time_ms) { |
1188 _mark_closure_time_ms = mark_closure_time_ms; | 817 _mark_closure_time_ms = mark_closure_time_ms; |
1189 } | 818 } |
1275 if (in_young_gc_mode()) { | 904 if (in_young_gc_mode()) { |
1276 _should_revert_to_full_young_gcs = false; | 905 _should_revert_to_full_young_gcs = false; |
1277 _last_full_young_gc = true; | 906 _last_full_young_gc = true; |
1278 _in_marking_window = false; | 907 _in_marking_window = false; |
1279 if (adaptive_young_list_length()) | 908 if (adaptive_young_list_length()) |
1280 calculate_young_list_target_config(); | 909 calculate_young_list_target_length(); |
1281 } | 910 } |
1282 } | 911 } |
1283 | 912 |
1284 void G1CollectorPolicy::record_concurrent_pause() { | 913 void G1CollectorPolicy::record_concurrent_pause() { |
1285 if (_stop_world_start > 0.0) { | 914 if (_stop_world_start > 0.0) { |
1510 "Negative collection"); | 1139 "Negative collection"); |
1511 | 1140 |
1512 size_t freed_bytes = | 1141 size_t freed_bytes = |
1513 _cur_collection_pause_used_at_start_bytes - cur_used_bytes; | 1142 _cur_collection_pause_used_at_start_bytes - cur_used_bytes; |
1514 size_t surviving_bytes = _collection_set_bytes_used_before - freed_bytes; | 1143 size_t surviving_bytes = _collection_set_bytes_used_before - freed_bytes; |
1144 | |
1515 double survival_fraction = | 1145 double survival_fraction = |
1516 (double)surviving_bytes/ | 1146 (double)surviving_bytes/ |
1517 (double)_collection_set_bytes_used_before; | 1147 (double)_collection_set_bytes_used_before; |
1518 | 1148 |
1519 _n_pauses++; | 1149 _n_pauses++; |
1597 summary = _summary; | 1227 summary = _summary; |
1598 } | 1228 } |
1599 | 1229 |
1600 double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms); | 1230 double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms); |
1601 double mark_stack_scan_time = avg_value(_par_last_mark_stack_scan_times_ms); | 1231 double mark_stack_scan_time = avg_value(_par_last_mark_stack_scan_times_ms); |
1602 double scan_only_time = avg_value(_par_last_scan_only_times_ms); | |
1603 double scan_only_regions_scanned = | |
1604 sum_of_values(_par_last_scan_only_regions_scanned); | |
1605 double update_rs_time = avg_value(_par_last_update_rs_times_ms); | 1232 double update_rs_time = avg_value(_par_last_update_rs_times_ms); |
1606 double update_rs_processed_buffers = | 1233 double update_rs_processed_buffers = |
1607 sum_of_values(_par_last_update_rs_processed_buffers); | 1234 sum_of_values(_par_last_update_rs_processed_buffers); |
1608 double scan_rs_time = avg_value(_par_last_scan_rs_times_ms); | 1235 double scan_rs_time = avg_value(_par_last_scan_rs_times_ms); |
1609 double obj_copy_time = avg_value(_par_last_obj_copy_times_ms); | 1236 double obj_copy_time = avg_value(_par_last_obj_copy_times_ms); |
1610 double termination_time = avg_value(_par_last_termination_times_ms); | 1237 double termination_time = avg_value(_par_last_termination_times_ms); |
1611 | 1238 |
1612 double parallel_other_time = _cur_collection_par_time_ms - | 1239 double parallel_other_time = _cur_collection_par_time_ms - |
1613 (update_rs_time + ext_root_scan_time + mark_stack_scan_time + | 1240 (update_rs_time + ext_root_scan_time + mark_stack_scan_time + |
1614 scan_only_time + scan_rs_time + obj_copy_time + termination_time); | 1241 scan_rs_time + obj_copy_time + termination_time); |
1615 if (update_stats) { | 1242 if (update_stats) { |
1616 MainBodySummary* body_summary = summary->main_body_summary(); | 1243 MainBodySummary* body_summary = summary->main_body_summary(); |
1617 guarantee(body_summary != NULL, "should not be null!"); | 1244 guarantee(body_summary != NULL, "should not be null!"); |
1618 | 1245 |
1619 if (_satb_drain_time_set) | 1246 if (_satb_drain_time_set) |
1620 body_summary->record_satb_drain_time_ms(_cur_satb_drain_time_ms); | 1247 body_summary->record_satb_drain_time_ms(_cur_satb_drain_time_ms); |
1621 else | 1248 else |
1622 body_summary->record_satb_drain_time_ms(0.0); | 1249 body_summary->record_satb_drain_time_ms(0.0); |
1623 body_summary->record_ext_root_scan_time_ms(ext_root_scan_time); | 1250 body_summary->record_ext_root_scan_time_ms(ext_root_scan_time); |
1624 body_summary->record_mark_stack_scan_time_ms(mark_stack_scan_time); | 1251 body_summary->record_mark_stack_scan_time_ms(mark_stack_scan_time); |
1625 body_summary->record_scan_only_time_ms(scan_only_time); | |
1626 body_summary->record_update_rs_time_ms(update_rs_time); | 1252 body_summary->record_update_rs_time_ms(update_rs_time); |
1627 body_summary->record_scan_rs_time_ms(scan_rs_time); | 1253 body_summary->record_scan_rs_time_ms(scan_rs_time); |
1628 body_summary->record_obj_copy_time_ms(obj_copy_time); | 1254 body_summary->record_obj_copy_time_ms(obj_copy_time); |
1629 if (parallel) { | 1255 if (parallel) { |
1630 body_summary->record_parallel_time_ms(_cur_collection_par_time_ms); | 1256 body_summary->record_parallel_time_ms(_cur_collection_par_time_ms); |
1674 if (parallel) | 1300 if (parallel) |
1675 other_time_ms -= _cur_collection_par_time_ms + _cur_clear_ct_time_ms; | 1301 other_time_ms -= _cur_collection_par_time_ms + _cur_clear_ct_time_ms; |
1676 else | 1302 else |
1677 other_time_ms -= | 1303 other_time_ms -= |
1678 update_rs_time + | 1304 update_rs_time + |
1679 ext_root_scan_time + mark_stack_scan_time + scan_only_time + | 1305 ext_root_scan_time + mark_stack_scan_time + |
1680 scan_rs_time + obj_copy_time; | 1306 scan_rs_time + obj_copy_time; |
1681 } | 1307 } |
1682 | 1308 |
1683 if (PrintGCDetails) { | 1309 if (PrintGCDetails) { |
1684 gclog_or_tty->print_cr("%s%s, %1.8lf secs]", | 1310 gclog_or_tty->print_cr("%s%s, %1.8lf secs]", |
1699 print_par_stats(2, "Update RS", _par_last_update_rs_times_ms); | 1325 print_par_stats(2, "Update RS", _par_last_update_rs_times_ms); |
1700 print_par_buffers(3, "Processed Buffers", | 1326 print_par_buffers(3, "Processed Buffers", |
1701 _par_last_update_rs_processed_buffers, true); | 1327 _par_last_update_rs_processed_buffers, true); |
1702 print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms); | 1328 print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms); |
1703 print_par_stats(2, "Mark Stack Scanning", _par_last_mark_stack_scan_times_ms); | 1329 print_par_stats(2, "Mark Stack Scanning", _par_last_mark_stack_scan_times_ms); |
1704 print_par_stats(2, "Scan-Only Scanning", _par_last_scan_only_times_ms); | |
1705 print_par_buffers(3, "Scan-Only Regions", | |
1706 _par_last_scan_only_regions_scanned, true); | |
1707 print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms); | 1330 print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms); |
1708 print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms); | 1331 print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms); |
1709 print_par_stats(2, "Termination", _par_last_termination_times_ms); | 1332 print_par_stats(2, "Termination", _par_last_termination_times_ms); |
1710 print_stats(2, "Other", parallel_other_time); | 1333 print_stats(2, "Other", parallel_other_time); |
1711 print_stats(1, "Clear CT", _cur_clear_ct_time_ms); | 1334 print_stats(1, "Clear CT", _cur_clear_ct_time_ms); |
1713 print_stats(1, "Update RS", update_rs_time); | 1336 print_stats(1, "Update RS", update_rs_time); |
1714 print_stats(2, "Processed Buffers", | 1337 print_stats(2, "Processed Buffers", |
1715 (int)update_rs_processed_buffers); | 1338 (int)update_rs_processed_buffers); |
1716 print_stats(1, "Ext Root Scanning", ext_root_scan_time); | 1339 print_stats(1, "Ext Root Scanning", ext_root_scan_time); |
1717 print_stats(1, "Mark Stack Scanning", mark_stack_scan_time); | 1340 print_stats(1, "Mark Stack Scanning", mark_stack_scan_time); |
1718 print_stats(1, "Scan-Only Scanning", scan_only_time); | |
1719 print_stats(1, "Scan RS", scan_rs_time); | 1341 print_stats(1, "Scan RS", scan_rs_time); |
1720 print_stats(1, "Object Copying", obj_copy_time); | 1342 print_stats(1, "Object Copying", obj_copy_time); |
1721 } | 1343 } |
1722 } | 1344 } |
1723 #ifndef PRODUCT | 1345 #ifndef PRODUCT |
1728 if (_num_cc_clears > 0) { | 1350 if (_num_cc_clears > 0) { |
1729 print_stats(1, "Avg Clear CC", _cum_clear_cc_time_ms / ((double)_num_cc_clears)); | 1351 print_stats(1, "Avg Clear CC", _cum_clear_cc_time_ms / ((double)_num_cc_clears)); |
1730 } | 1352 } |
1731 #endif | 1353 #endif |
1732 print_stats(1, "Other", other_time_ms); | 1354 print_stats(1, "Other", other_time_ms); |
1355 print_stats(2, "Choose CSet", _recorded_young_cset_choice_time_ms); | |
1356 | |
1733 for (int i = 0; i < _aux_num; ++i) { | 1357 for (int i = 0; i < _aux_num; ++i) { |
1734 if (_cur_aux_times_set[i]) { | 1358 if (_cur_aux_times_set[i]) { |
1735 char buffer[96]; | 1359 char buffer[96]; |
1736 sprintf(buffer, "Aux%d", i); | 1360 sprintf(buffer, "Aux%d", i); |
1737 print_stats(1, buffer, _cur_aux_times_ms[i]); | 1361 print_stats(1, buffer, _cur_aux_times_ms[i]); |
1813 if (_pending_cards > 0) { | 1437 if (_pending_cards > 0) { |
1814 cost_per_card_ms = update_rs_time / (double) _pending_cards; | 1438 cost_per_card_ms = update_rs_time / (double) _pending_cards; |
1815 _cost_per_card_ms_seq->add(cost_per_card_ms); | 1439 _cost_per_card_ms_seq->add(cost_per_card_ms); |
1816 } | 1440 } |
1817 | 1441 |
1818 double cost_per_scan_only_region_ms = 0.0; | |
1819 if (scan_only_regions_scanned > 0.0) { | |
1820 cost_per_scan_only_region_ms = | |
1821 scan_only_time / scan_only_regions_scanned; | |
1822 if (_in_marking_window_im) | |
1823 _cost_per_scan_only_region_ms_during_cm_seq->add(cost_per_scan_only_region_ms); | |
1824 else | |
1825 _cost_per_scan_only_region_ms_seq->add(cost_per_scan_only_region_ms); | |
1826 } | |
1827 | |
1828 size_t cards_scanned = _g1->cards_scanned(); | 1442 size_t cards_scanned = _g1->cards_scanned(); |
1829 | 1443 |
1830 double cost_per_entry_ms = 0.0; | 1444 double cost_per_entry_ms = 0.0; |
1831 if (cards_scanned > 10) { | 1445 if (cards_scanned > 10) { |
1832 cost_per_entry_ms = scan_rs_time / (double) cards_scanned; | 1446 cost_per_entry_ms = scan_rs_time / (double) cards_scanned; |
1858 else | 1472 else |
1859 _cost_per_byte_ms_seq->add(cost_per_byte_ms); | 1473 _cost_per_byte_ms_seq->add(cost_per_byte_ms); |
1860 } | 1474 } |
1861 | 1475 |
1862 double all_other_time_ms = pause_time_ms - | 1476 double all_other_time_ms = pause_time_ms - |
1863 (update_rs_time + scan_only_time + scan_rs_time + obj_copy_time + | 1477 (update_rs_time + scan_rs_time + obj_copy_time + |
1864 _mark_closure_time_ms + termination_time); | 1478 _mark_closure_time_ms + termination_time); |
1865 | 1479 |
1866 double young_other_time_ms = 0.0; | 1480 double young_other_time_ms = 0.0; |
1867 if (_recorded_young_regions > 0) { | 1481 if (_recorded_young_regions > 0) { |
1868 young_other_time_ms = | 1482 young_other_time_ms = |
1905 _expensive_region_limit_ms = expensive_region_limit_ms; | 1519 _expensive_region_limit_ms = expensive_region_limit_ms; |
1906 | 1520 |
1907 if (PREDICTIONS_VERBOSE) { | 1521 if (PREDICTIONS_VERBOSE) { |
1908 gclog_or_tty->print_cr(""); | 1522 gclog_or_tty->print_cr(""); |
1909 gclog_or_tty->print_cr("PREDICTIONS %1.4lf %d " | 1523 gclog_or_tty->print_cr("PREDICTIONS %1.4lf %d " |
1910 "REGIONS %d %d %d %d " | 1524 "REGIONS %d %d %d " |
1911 "PENDING_CARDS %d %d " | 1525 "PENDING_CARDS %d %d " |
1912 "CARDS_SCANNED %d %d " | 1526 "CARDS_SCANNED %d %d " |
1913 "RS_LENGTHS %d %d " | 1527 "RS_LENGTHS %d %d " |
1914 "SCAN_ONLY_SCAN %1.6lf %1.6lf " | |
1915 "RS_UPDATE %1.6lf %1.6lf RS_SCAN %1.6lf %1.6lf " | 1528 "RS_UPDATE %1.6lf %1.6lf RS_SCAN %1.6lf %1.6lf " |
1916 "SURVIVAL_RATIO %1.6lf %1.6lf " | 1529 "SURVIVAL_RATIO %1.6lf %1.6lf " |
1917 "OBJECT_COPY %1.6lf %1.6lf OTHER_CONSTANT %1.6lf %1.6lf " | 1530 "OBJECT_COPY %1.6lf %1.6lf OTHER_CONSTANT %1.6lf %1.6lf " |
1918 "OTHER_YOUNG %1.6lf %1.6lf " | 1531 "OTHER_YOUNG %1.6lf %1.6lf " |
1919 "OTHER_NON_YOUNG %1.6lf %1.6lf " | 1532 "OTHER_NON_YOUNG %1.6lf %1.6lf " |
1922 _cur_collection_start_sec, | 1535 _cur_collection_start_sec, |
1923 (!_last_young_gc_full) ? 2 : | 1536 (!_last_young_gc_full) ? 2 : |
1924 (last_pause_included_initial_mark) ? 1 : 0, | 1537 (last_pause_included_initial_mark) ? 1 : 0, |
1925 _recorded_region_num, | 1538 _recorded_region_num, |
1926 _recorded_young_regions, | 1539 _recorded_young_regions, |
1927 _recorded_scan_only_regions, | |
1928 _recorded_non_young_regions, | 1540 _recorded_non_young_regions, |
1929 _predicted_pending_cards, _pending_cards, | 1541 _predicted_pending_cards, _pending_cards, |
1930 _predicted_cards_scanned, cards_scanned, | 1542 _predicted_cards_scanned, cards_scanned, |
1931 _predicted_rs_lengths, _max_rs_lengths, | 1543 _predicted_rs_lengths, _max_rs_lengths, |
1932 _predicted_scan_only_scan_time_ms, scan_only_time, | |
1933 _predicted_rs_update_time_ms, update_rs_time, | 1544 _predicted_rs_update_time_ms, update_rs_time, |
1934 _predicted_rs_scan_time_ms, scan_rs_time, | 1545 _predicted_rs_scan_time_ms, scan_rs_time, |
1935 _predicted_survival_ratio, survival_ratio, | 1546 _predicted_survival_ratio, survival_ratio, |
1936 _predicted_object_copy_time_ms, obj_copy_time, | 1547 _predicted_object_copy_time_ms, obj_copy_time, |
1937 _predicted_constant_other_time_ms, constant_other_time_ms, | 1548 _predicted_constant_other_time_ms, constant_other_time_ms, |
1952 } | 1563 } |
1953 | 1564 |
1954 _in_marking_window = new_in_marking_window; | 1565 _in_marking_window = new_in_marking_window; |
1955 _in_marking_window_im = new_in_marking_window_im; | 1566 _in_marking_window_im = new_in_marking_window_im; |
1956 _free_regions_at_end_of_collection = _g1->free_regions(); | 1567 _free_regions_at_end_of_collection = _g1->free_regions(); |
1957 _scan_only_regions_at_end_of_collection = _g1->young_list_length(); | |
1958 calculate_young_list_min_length(); | 1568 calculate_young_list_min_length(); |
1959 calculate_young_list_target_config(); | 1569 calculate_young_list_target_length(); |
1960 | 1570 |
1961 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. | 1571 // Note that _mmu_tracker->max_gc_time() returns the time in seconds. |
1962 double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; | 1572 double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0; |
1963 adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); | 1573 adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms); |
1964 | |
1965 // </NEW PREDICTION> | 1574 // </NEW PREDICTION> |
1966 | 1575 |
1967 _target_pause_time_ms = -1.0; | 1576 _target_pause_time_ms = -1.0; |
1968 } | 1577 } |
1969 | 1578 |
2014 G1CollectorPolicy:: | 1623 G1CollectorPolicy:: |
2015 predict_young_collection_elapsed_time_ms(size_t adjustment) { | 1624 predict_young_collection_elapsed_time_ms(size_t adjustment) { |
2016 guarantee( adjustment == 0 || adjustment == 1, "invariant" ); | 1625 guarantee( adjustment == 0 || adjustment == 1, "invariant" ); |
2017 | 1626 |
2018 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | 1627 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
2019 size_t young_num = g1h->young_list_length(); | 1628 size_t young_num = g1h->young_list()->length(); |
2020 if (young_num == 0) | 1629 if (young_num == 0) |
2021 return 0.0; | 1630 return 0.0; |
2022 | 1631 |
2023 young_num += adjustment; | 1632 young_num += adjustment; |
2024 size_t pending_cards = predict_pending_cards(); | 1633 size_t pending_cards = predict_pending_cards(); |
2025 size_t rs_lengths = g1h->young_list_sampled_rs_lengths() + | 1634 size_t rs_lengths = g1h->young_list()->sampled_rs_lengths() + |
2026 predict_rs_length_diff(); | 1635 predict_rs_length_diff(); |
2027 size_t card_num; | 1636 size_t card_num; |
2028 if (full_young_gcs()) | 1637 if (full_young_gcs()) |
2029 card_num = predict_young_card_num(rs_lengths); | 1638 card_num = predict_young_card_num(rs_lengths); |
2030 else | 1639 else |
2104 } | 1713 } |
2105 | 1714 |
2106 void | 1715 void |
2107 G1CollectorPolicy::start_recording_regions() { | 1716 G1CollectorPolicy::start_recording_regions() { |
2108 _recorded_rs_lengths = 0; | 1717 _recorded_rs_lengths = 0; |
2109 _recorded_scan_only_regions = 0; | |
2110 _recorded_young_regions = 0; | 1718 _recorded_young_regions = 0; |
2111 _recorded_non_young_regions = 0; | 1719 _recorded_non_young_regions = 0; |
2112 | 1720 |
2113 #if PREDICTIONS_VERBOSE | 1721 #if PREDICTIONS_VERBOSE |
2114 _predicted_rs_lengths = 0; | |
2115 _predicted_cards_scanned = 0; | |
2116 | |
2117 _recorded_marked_bytes = 0; | 1722 _recorded_marked_bytes = 0; |
2118 _recorded_young_bytes = 0; | 1723 _recorded_young_bytes = 0; |
2119 _predicted_bytes_to_copy = 0; | 1724 _predicted_bytes_to_copy = 0; |
1725 _predicted_rs_lengths = 0; | |
1726 _predicted_cards_scanned = 0; | |
2120 #endif // PREDICTIONS_VERBOSE | 1727 #endif // PREDICTIONS_VERBOSE |
2121 } | 1728 } |
2122 | 1729 |
2123 void | 1730 void |
2124 G1CollectorPolicy::record_cset_region(HeapRegion* hr, bool young) { | 1731 G1CollectorPolicy::record_cset_region_info(HeapRegion* hr, bool young) { |
2125 if (young) { | |
2126 ++_recorded_young_regions; | |
2127 } else { | |
2128 ++_recorded_non_young_regions; | |
2129 } | |
2130 #if PREDICTIONS_VERBOSE | 1732 #if PREDICTIONS_VERBOSE |
2131 if (young) { | 1733 if (!young) { |
2132 _recorded_young_bytes += hr->used(); | |
2133 } else { | |
2134 _recorded_marked_bytes += hr->max_live_bytes(); | 1734 _recorded_marked_bytes += hr->max_live_bytes(); |
2135 } | 1735 } |
2136 _predicted_bytes_to_copy += predict_bytes_to_copy(hr); | 1736 _predicted_bytes_to_copy += predict_bytes_to_copy(hr); |
2137 #endif // PREDICTIONS_VERBOSE | 1737 #endif // PREDICTIONS_VERBOSE |
2138 | 1738 |
2139 size_t rs_length = hr->rem_set()->occupied(); | 1739 size_t rs_length = hr->rem_set()->occupied(); |
2140 _recorded_rs_lengths += rs_length; | 1740 _recorded_rs_lengths += rs_length; |
2141 } | 1741 } |
2142 | 1742 |
2143 void | 1743 void |
2144 G1CollectorPolicy::record_scan_only_regions(size_t scan_only_length) { | 1744 G1CollectorPolicy::record_non_young_cset_region(HeapRegion* hr) { |
2145 _recorded_scan_only_regions = scan_only_length; | 1745 assert(!hr->is_young(), "should not call this"); |
1746 ++_recorded_non_young_regions; | |
1747 record_cset_region_info(hr, false); | |
1748 } | |
1749 | |
1750 void | |
1751 G1CollectorPolicy::set_recorded_young_regions(size_t n_regions) { | |
1752 _recorded_young_regions = n_regions; | |
1753 } | |
1754 | |
1755 void G1CollectorPolicy::set_recorded_young_bytes(size_t bytes) { | |
1756 #if PREDICTIONS_VERBOSE | |
1757 _recorded_young_bytes = bytes; | |
1758 #endif // PREDICTIONS_VERBOSE | |
1759 } | |
1760 | |
1761 void G1CollectorPolicy::set_recorded_rs_lengths(size_t rs_lengths) { | |
1762 _recorded_rs_lengths = rs_lengths; | |
1763 } | |
1764 | |
1765 void G1CollectorPolicy::set_predicted_bytes_to_copy(size_t bytes) { | |
1766 _predicted_bytes_to_copy = bytes; | |
2146 } | 1767 } |
2147 | 1768 |
2148 void | 1769 void |
2149 G1CollectorPolicy::end_recording_regions() { | 1770 G1CollectorPolicy::end_recording_regions() { |
1771 // The _predicted_pause_time_ms field is referenced in code | |
1772 // not under PREDICTIONS_VERBOSE. Let's initialize it. | |
1773 _predicted_pause_time_ms = -1.0; | |
1774 | |
2150 #if PREDICTIONS_VERBOSE | 1775 #if PREDICTIONS_VERBOSE |
2151 _predicted_pending_cards = predict_pending_cards(); | 1776 _predicted_pending_cards = predict_pending_cards(); |
2152 _predicted_rs_lengths = _recorded_rs_lengths + predict_rs_length_diff(); | 1777 _predicted_rs_lengths = _recorded_rs_lengths + predict_rs_length_diff(); |
2153 if (full_young_gcs()) | 1778 if (full_young_gcs()) |
2154 _predicted_cards_scanned += predict_young_card_num(_predicted_rs_lengths); | 1779 _predicted_cards_scanned += predict_young_card_num(_predicted_rs_lengths); |
2155 else | 1780 else |
2156 _predicted_cards_scanned += | 1781 _predicted_cards_scanned += |
2157 predict_non_young_card_num(_predicted_rs_lengths); | 1782 predict_non_young_card_num(_predicted_rs_lengths); |
2158 _recorded_region_num = _recorded_young_regions + _recorded_non_young_regions; | 1783 _recorded_region_num = _recorded_young_regions + _recorded_non_young_regions; |
2159 | 1784 |
2160 _predicted_scan_only_scan_time_ms = | |
2161 predict_scan_only_time_ms(_recorded_scan_only_regions); | |
2162 _predicted_rs_update_time_ms = | 1785 _predicted_rs_update_time_ms = |
2163 predict_rs_update_time_ms(_g1->pending_card_num()); | 1786 predict_rs_update_time_ms(_g1->pending_card_num()); |
2164 _predicted_rs_scan_time_ms = | 1787 _predicted_rs_scan_time_ms = |
2165 predict_rs_scan_time_ms(_predicted_cards_scanned); | 1788 predict_rs_scan_time_ms(_predicted_cards_scanned); |
2166 _predicted_object_copy_time_ms = | 1789 _predicted_object_copy_time_ms = |
2171 predict_young_other_time_ms(_recorded_young_regions); | 1794 predict_young_other_time_ms(_recorded_young_regions); |
2172 _predicted_non_young_other_time_ms = | 1795 _predicted_non_young_other_time_ms = |
2173 predict_non_young_other_time_ms(_recorded_non_young_regions); | 1796 predict_non_young_other_time_ms(_recorded_non_young_regions); |
2174 | 1797 |
2175 _predicted_pause_time_ms = | 1798 _predicted_pause_time_ms = |
2176 _predicted_scan_only_scan_time_ms + | |
2177 _predicted_rs_update_time_ms + | 1799 _predicted_rs_update_time_ms + |
2178 _predicted_rs_scan_time_ms + | 1800 _predicted_rs_scan_time_ms + |
2179 _predicted_object_copy_time_ms + | 1801 _predicted_object_copy_time_ms + |
2180 _predicted_constant_other_time_ms + | 1802 _predicted_constant_other_time_ms + |
2181 _predicted_young_other_time_ms + | 1803 _predicted_young_other_time_ms + |
2461 print_summary(2, "Update RS", body_summary->get_update_rs_seq()); | 2083 print_summary(2, "Update RS", body_summary->get_update_rs_seq()); |
2462 print_summary(2, "Ext Root Scanning", | 2084 print_summary(2, "Ext Root Scanning", |
2463 body_summary->get_ext_root_scan_seq()); | 2085 body_summary->get_ext_root_scan_seq()); |
2464 print_summary(2, "Mark Stack Scanning", | 2086 print_summary(2, "Mark Stack Scanning", |
2465 body_summary->get_mark_stack_scan_seq()); | 2087 body_summary->get_mark_stack_scan_seq()); |
2466 print_summary(2, "Scan-Only Scanning", | |
2467 body_summary->get_scan_only_seq()); | |
2468 print_summary(2, "Scan RS", body_summary->get_scan_rs_seq()); | 2088 print_summary(2, "Scan RS", body_summary->get_scan_rs_seq()); |
2469 print_summary(2, "Object Copy", body_summary->get_obj_copy_seq()); | 2089 print_summary(2, "Object Copy", body_summary->get_obj_copy_seq()); |
2470 print_summary(2, "Termination", body_summary->get_termination_seq()); | 2090 print_summary(2, "Termination", body_summary->get_termination_seq()); |
2471 print_summary(2, "Other", body_summary->get_parallel_other_seq()); | 2091 print_summary(2, "Other", body_summary->get_parallel_other_seq()); |
2472 { | 2092 { |
2473 NumberSeq* other_parts[] = { | 2093 NumberSeq* other_parts[] = { |
2474 body_summary->get_update_rs_seq(), | 2094 body_summary->get_update_rs_seq(), |
2475 body_summary->get_ext_root_scan_seq(), | 2095 body_summary->get_ext_root_scan_seq(), |
2476 body_summary->get_mark_stack_scan_seq(), | 2096 body_summary->get_mark_stack_scan_seq(), |
2477 body_summary->get_scan_only_seq(), | |
2478 body_summary->get_scan_rs_seq(), | 2097 body_summary->get_scan_rs_seq(), |
2479 body_summary->get_obj_copy_seq(), | 2098 body_summary->get_obj_copy_seq(), |
2480 body_summary->get_termination_seq() | 2099 body_summary->get_termination_seq() |
2481 }; | 2100 }; |
2482 NumberSeq calc_other_times_ms(body_summary->get_parallel_seq(), | 2101 NumberSeq calc_other_times_ms(body_summary->get_parallel_seq(), |
2490 print_summary(1, "Update RS", body_summary->get_update_rs_seq()); | 2109 print_summary(1, "Update RS", body_summary->get_update_rs_seq()); |
2491 print_summary(1, "Ext Root Scanning", | 2110 print_summary(1, "Ext Root Scanning", |
2492 body_summary->get_ext_root_scan_seq()); | 2111 body_summary->get_ext_root_scan_seq()); |
2493 print_summary(1, "Mark Stack Scanning", | 2112 print_summary(1, "Mark Stack Scanning", |
2494 body_summary->get_mark_stack_scan_seq()); | 2113 body_summary->get_mark_stack_scan_seq()); |
2495 print_summary(1, "Scan-Only Scanning", | |
2496 body_summary->get_scan_only_seq()); | |
2497 print_summary(1, "Scan RS", body_summary->get_scan_rs_seq()); | 2114 print_summary(1, "Scan RS", body_summary->get_scan_rs_seq()); |
2498 print_summary(1, "Object Copy", body_summary->get_obj_copy_seq()); | 2115 print_summary(1, "Object Copy", body_summary->get_obj_copy_seq()); |
2499 } | 2116 } |
2500 } | 2117 } |
2501 print_summary(1, "Other", summary->get_other_seq()); | 2118 print_summary(1, "Other", summary->get_other_seq()); |
2517 NumberSeq* other_parts[] = { | 2134 NumberSeq* other_parts[] = { |
2518 body_summary->get_satb_drain_seq(), | 2135 body_summary->get_satb_drain_seq(), |
2519 body_summary->get_update_rs_seq(), | 2136 body_summary->get_update_rs_seq(), |
2520 body_summary->get_ext_root_scan_seq(), | 2137 body_summary->get_ext_root_scan_seq(), |
2521 body_summary->get_mark_stack_scan_seq(), | 2138 body_summary->get_mark_stack_scan_seq(), |
2522 body_summary->get_scan_only_seq(), | |
2523 body_summary->get_scan_rs_seq(), | 2139 body_summary->get_scan_rs_seq(), |
2524 body_summary->get_obj_copy_seq() | 2140 body_summary->get_obj_copy_seq() |
2525 }; | 2141 }; |
2526 calc_other_times_ms = NumberSeq(summary->get_total_seq(), | 2142 calc_other_times_ms = NumberSeq(summary->get_total_seq(), |
2527 7, other_parts); | 2143 7, other_parts); |
2611 | 2227 |
2612 bool | 2228 bool |
2613 G1CollectorPolicy::should_add_next_region_to_young_list() { | 2229 G1CollectorPolicy::should_add_next_region_to_young_list() { |
2614 assert(in_young_gc_mode(), "should be in young GC mode"); | 2230 assert(in_young_gc_mode(), "should be in young GC mode"); |
2615 bool ret; | 2231 bool ret; |
2616 size_t young_list_length = _g1->young_list_length(); | 2232 size_t young_list_length = _g1->young_list()->length(); |
2617 size_t young_list_max_length = _young_list_target_length; | 2233 size_t young_list_max_length = _young_list_target_length; |
2618 if (G1FixedEdenSize) { | 2234 if (G1FixedEdenSize) { |
2619 young_list_max_length -= _max_survivor_regions; | 2235 young_list_max_length -= _max_survivor_regions; |
2620 } | 2236 } |
2621 if (young_list_length < young_list_max_length) { | 2237 if (young_list_length < young_list_max_length) { |
2674 G1CollectorPolicy_BestRegionsFirst::should_do_collection_pause(size_t | 2290 G1CollectorPolicy_BestRegionsFirst::should_do_collection_pause(size_t |
2675 word_size) { | 2291 word_size) { |
2676 assert(_g1->regions_accounted_for(), "Region leakage!"); | 2292 assert(_g1->regions_accounted_for(), "Region leakage!"); |
2677 double max_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; | 2293 double max_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0; |
2678 | 2294 |
2679 size_t young_list_length = _g1->young_list_length(); | 2295 size_t young_list_length = _g1->young_list()->length(); |
2680 size_t young_list_max_length = _young_list_target_length; | 2296 size_t young_list_max_length = _young_list_target_length; |
2681 if (G1FixedEdenSize) { | 2297 if (G1FixedEdenSize) { |
2682 young_list_max_length -= _max_survivor_regions; | 2298 young_list_max_length -= _max_survivor_regions; |
2683 } | 2299 } |
2684 bool reached_target_length = young_list_length >= young_list_max_length; | 2300 bool reached_target_length = young_list_length >= young_list_max_length; |
2685 | 2301 |
2686 if (in_young_gc_mode()) { | 2302 if (in_young_gc_mode()) { |
2687 if (reached_target_length) { | 2303 if (reached_target_length) { |
2688 assert( young_list_length > 0 && _g1->young_list_length() > 0, | 2304 assert( young_list_length > 0 && _g1->young_list()->length() > 0, |
2689 "invariant" ); | 2305 "invariant" ); |
2690 _target_pause_time_ms = max_pause_time_ms; | 2306 _target_pause_time_ms = max_pause_time_ms; |
2691 return true; | 2307 return true; |
2692 } | 2308 } |
2693 } else { | 2309 } else { |
2944 gclog_or_tty->print_cr(" work2: %8.3f ms.", | 2560 gclog_or_tty->print_cr(" work2: %8.3f ms.", |
2945 (work2_end - sort_end)*1000.0); | 2561 (work2_end - sort_end)*1000.0); |
2946 } | 2562 } |
2947 } | 2563 } |
2948 | 2564 |
2949 // Add the heap region to the collection set and return the conservative | 2565 // Add the heap region at the head of the non-incremental collection set |
2950 // estimate of the number of live bytes. | |
2951 void G1CollectorPolicy:: | 2566 void G1CollectorPolicy:: |
2952 add_to_collection_set(HeapRegion* hr) { | 2567 add_to_collection_set(HeapRegion* hr) { |
2568 assert(_inc_cset_build_state == Active, "Precondition"); | |
2569 assert(!hr->is_young(), "non-incremental add of young region"); | |
2570 | |
2953 if (G1PrintHeapRegions) { | 2571 if (G1PrintHeapRegions) { |
2954 gclog_or_tty->print_cr("added region to cset " | 2572 gclog_or_tty->print_cr("added region to cset " |
2955 "%d:["PTR_FORMAT", "PTR_FORMAT"], " | 2573 "%d:["PTR_FORMAT", "PTR_FORMAT"], " |
2956 "top "PTR_FORMAT", %s", | 2574 "top "PTR_FORMAT", %s", |
2957 hr->hrs_index(), hr->bottom(), hr->end(), | 2575 hr->hrs_index(), hr->bottom(), hr->end(), |
2959 } | 2577 } |
2960 | 2578 |
2961 if (_g1->mark_in_progress()) | 2579 if (_g1->mark_in_progress()) |
2962 _g1->concurrent_mark()->registerCSetRegion(hr); | 2580 _g1->concurrent_mark()->registerCSetRegion(hr); |
2963 | 2581 |
2964 assert(!hr->in_collection_set(), | 2582 assert(!hr->in_collection_set(), "should not already be in the CSet"); |
2965 "should not already be in the CSet"); | |
2966 hr->set_in_collection_set(true); | 2583 hr->set_in_collection_set(true); |
2967 hr->set_next_in_collection_set(_collection_set); | 2584 hr->set_next_in_collection_set(_collection_set); |
2968 _collection_set = hr; | 2585 _collection_set = hr; |
2969 _collection_set_size++; | 2586 _collection_set_size++; |
2970 _collection_set_bytes_used_before += hr->used(); | 2587 _collection_set_bytes_used_before += hr->used(); |
2971 _g1->register_region_with_in_cset_fast_test(hr); | 2588 _g1->register_region_with_in_cset_fast_test(hr); |
2972 } | 2589 } |
2973 | 2590 |
2974 void | 2591 // Initialize the per-collection-set information |
2975 G1CollectorPolicy_BestRegionsFirst:: | 2592 void G1CollectorPolicy::start_incremental_cset_building() { |
2976 choose_collection_set() { | 2593 assert(_inc_cset_build_state == Inactive, "Precondition"); |
2977 double non_young_start_time_sec; | 2594 |
2595 _inc_cset_head = NULL; | |
2596 _inc_cset_tail = NULL; | |
2597 _inc_cset_size = 0; | |
2598 _inc_cset_bytes_used_before = 0; | |
2599 | |
2600 if (in_young_gc_mode()) { | |
2601 _inc_cset_young_index = 0; | |
2602 } | |
2603 | |
2604 _inc_cset_max_finger = 0; | |
2605 _inc_cset_recorded_young_bytes = 0; | |
2606 _inc_cset_recorded_rs_lengths = 0; | |
2607 _inc_cset_predicted_elapsed_time_ms = 0; | |
2608 _inc_cset_predicted_bytes_to_copy = 0; | |
2609 _inc_cset_build_state = Active; | |
2610 } | |
2611 | |
2612 void G1CollectorPolicy::add_to_incremental_cset_info(HeapRegion* hr, size_t rs_length) { | |
2613 // This routine is used when: | |
2614 // * adding survivor regions to the incremental cset at the end of an | |
2615 // evacuation pause, | |
2616 // * adding the current allocation region to the incremental cset | |
2617 // when it is retired, and | |
2618 // * updating existing policy information for a region in the | |
2619 // incremental cset via young list RSet sampling. | |
2620 // Therefore this routine may be called at a safepoint by the | |
2621 // VM thread, or in-between safepoints by mutator threads (when | |
2622 // retiring the current allocation region) or a concurrent | |
2623 // refine thread (RSet sampling). | |
2624 | |
2625 double region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, true); | |
2626 size_t used_bytes = hr->used(); | |
2627 | |
2628 _inc_cset_recorded_rs_lengths += rs_length; | |
2629 _inc_cset_predicted_elapsed_time_ms += region_elapsed_time_ms; | |
2630 | |
2631 _inc_cset_bytes_used_before += used_bytes; | |
2632 | |
2633 // Cache the values we have added to the aggregated informtion | |
2634 // in the heap region in case we have to remove this region from | |
2635 // the incremental collection set, or it is updated by the | |
2636 // rset sampling code | |
2637 hr->set_recorded_rs_length(rs_length); | |
2638 hr->set_predicted_elapsed_time_ms(region_elapsed_time_ms); | |
2639 | |
2640 #if PREDICTIONS_VERBOSE | |
2641 size_t bytes_to_copy = predict_bytes_to_copy(hr); | |
2642 _inc_cset_predicted_bytes_to_copy += bytes_to_copy; | |
2643 | |
2644 // Record the number of bytes used in this region | |
2645 _inc_cset_recorded_young_bytes += used_bytes; | |
2646 | |
2647 // Cache the values we have added to the aggregated informtion | |
2648 // in the heap region in case we have to remove this region from | |
2649 // the incremental collection set, or it is updated by the | |
2650 // rset sampling code | |
2651 hr->set_predicted_bytes_to_copy(bytes_to_copy); | |
2652 #endif // PREDICTIONS_VERBOSE | |
2653 } | |
2654 | |
2655 void G1CollectorPolicy::remove_from_incremental_cset_info(HeapRegion* hr) { | |
2656 // This routine is currently only called as part of the updating of | |
2657 // existing policy information for regions in the incremental cset that | |
2658 // is performed by the concurrent refine thread(s) as part of young list | |
2659 // RSet sampling. Therefore we should not be at a safepoint. | |
2660 | |
2661 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at safepoint"); | |
2662 assert(hr->is_young(), "it should be"); | |
2663 | |
2664 size_t used_bytes = hr->used(); | |
2665 size_t old_rs_length = hr->recorded_rs_length(); | |
2666 double old_elapsed_time_ms = hr->predicted_elapsed_time_ms(); | |
2667 | |
2668 // Subtract the old recorded/predicted policy information for | |
2669 // the given heap region from the collection set info. | |
2670 _inc_cset_recorded_rs_lengths -= old_rs_length; | |
2671 _inc_cset_predicted_elapsed_time_ms -= old_elapsed_time_ms; | |
2672 | |
2673 _inc_cset_bytes_used_before -= used_bytes; | |
2674 | |
2675 // Clear the values cached in the heap region | |
2676 hr->set_recorded_rs_length(0); | |
2677 hr->set_predicted_elapsed_time_ms(0); | |
2678 | |
2679 #if PREDICTIONS_VERBOSE | |
2680 size_t old_predicted_bytes_to_copy = hr->predicted_bytes_to_copy(); | |
2681 _inc_cset_predicted_bytes_to_copy -= old_predicted_bytes_to_copy; | |
2682 | |
2683 // Subtract the number of bytes used in this region | |
2684 _inc_cset_recorded_young_bytes -= used_bytes; | |
2685 | |
2686 // Clear the values cached in the heap region | |
2687 hr->set_predicted_bytes_to_copy(0); | |
2688 #endif // PREDICTIONS_VERBOSE | |
2689 } | |
2690 | |
2691 void G1CollectorPolicy::update_incremental_cset_info(HeapRegion* hr, size_t new_rs_length) { | |
2692 // Update the collection set information that is dependent on the new RS length | |
2693 assert(hr->is_young(), "Precondition"); | |
2694 | |
2695 remove_from_incremental_cset_info(hr); | |
2696 add_to_incremental_cset_info(hr, new_rs_length); | |
2697 } | |
2698 | |
2699 void G1CollectorPolicy::add_region_to_incremental_cset_common(HeapRegion* hr) { | |
2700 assert( hr->is_young(), "invariant"); | |
2701 assert( hr->young_index_in_cset() == -1, "invariant" ); | |
2702 assert(_inc_cset_build_state == Active, "Precondition"); | |
2703 | |
2704 // We need to clear and set the cached recorded/cached collection set | |
2705 // information in the heap region here (before the region gets added | |
2706 // to the collection set). An individual heap region's cached values | |
2707 // are calculated, aggregated with the policy collection set info, | |
2708 // and cached in the heap region here (initially) and (subsequently) | |
2709 // by the Young List sampling code. | |
2710 | |
2711 size_t rs_length = hr->rem_set()->occupied(); | |
2712 add_to_incremental_cset_info(hr, rs_length); | |
2713 | |
2714 HeapWord* hr_end = hr->end(); | |
2715 _inc_cset_max_finger = MAX2(_inc_cset_max_finger, hr_end); | |
2716 | |
2717 assert(!hr->in_collection_set(), "invariant"); | |
2718 hr->set_in_collection_set(true); | |
2719 assert( hr->next_in_collection_set() == NULL, "invariant"); | |
2720 | |
2721 _inc_cset_size++; | |
2722 _g1->register_region_with_in_cset_fast_test(hr); | |
2723 | |
2724 hr->set_young_index_in_cset((int) _inc_cset_young_index); | |
2725 ++_inc_cset_young_index; | |
2726 } | |
2727 | |
2728 // Add the region at the RHS of the incremental cset | |
2729 void G1CollectorPolicy::add_region_to_incremental_cset_rhs(HeapRegion* hr) { | |
2730 // We should only ever be appending survivors at the end of a pause | |
2731 assert( hr->is_survivor(), "Logic"); | |
2732 | |
2733 // Do the 'common' stuff | |
2734 add_region_to_incremental_cset_common(hr); | |
2735 | |
2736 // Now add the region at the right hand side | |
2737 if (_inc_cset_tail == NULL) { | |
2738 assert(_inc_cset_head == NULL, "invariant"); | |
2739 _inc_cset_head = hr; | |
2740 } else { | |
2741 _inc_cset_tail->set_next_in_collection_set(hr); | |
2742 } | |
2743 _inc_cset_tail = hr; | |
2744 | |
2745 if (G1PrintHeapRegions) { | |
2746 gclog_or_tty->print_cr(" added region to incremental cset (RHS) " | |
2747 "%d:["PTR_FORMAT", "PTR_FORMAT"], " | |
2748 "top "PTR_FORMAT", young %s", | |
2749 hr->hrs_index(), hr->bottom(), hr->end(), | |
2750 hr->top(), (hr->is_young()) ? "YES" : "NO"); | |
2751 } | |
2752 } | |
2753 | |
2754 // Add the region to the LHS of the incremental cset | |
2755 void G1CollectorPolicy::add_region_to_incremental_cset_lhs(HeapRegion* hr) { | |
2756 // Survivors should be added to the RHS at the end of a pause | |
2757 assert(!hr->is_survivor(), "Logic"); | |
2758 | |
2759 // Do the 'common' stuff | |
2760 add_region_to_incremental_cset_common(hr); | |
2761 | |
2762 // Add the region at the left hand side | |
2763 hr->set_next_in_collection_set(_inc_cset_head); | |
2764 if (_inc_cset_head == NULL) { | |
2765 assert(_inc_cset_tail == NULL, "Invariant"); | |
2766 _inc_cset_tail = hr; | |
2767 } | |
2768 _inc_cset_head = hr; | |
2769 | |
2770 if (G1PrintHeapRegions) { | |
2771 gclog_or_tty->print_cr(" added region to incremental cset (LHS) " | |
2772 "%d:["PTR_FORMAT", "PTR_FORMAT"], " | |
2773 "top "PTR_FORMAT", young %s", | |
2774 hr->hrs_index(), hr->bottom(), hr->end(), | |
2775 hr->top(), (hr->is_young()) ? "YES" : "NO"); | |
2776 } | |
2777 } | |
2778 | |
2779 #ifndef PRODUCT | |
2780 void G1CollectorPolicy::print_collection_set(HeapRegion* list_head, outputStream* st) { | |
2781 assert(list_head == inc_cset_head() || list_head == collection_set(), "must be"); | |
2782 | |
2783 st->print_cr("\nCollection_set:"); | |
2784 HeapRegion* csr = list_head; | |
2785 while (csr != NULL) { | |
2786 HeapRegion* next = csr->next_in_collection_set(); | |
2787 assert(csr->in_collection_set(), "bad CS"); | |
2788 st->print_cr(" [%08x-%08x], t: %08x, P: %08x, N: %08x, C: %08x, " | |
2789 "age: %4d, y: %d, surv: %d", | |
2790 csr->bottom(), csr->end(), | |
2791 csr->top(), | |
2792 csr->prev_top_at_mark_start(), | |
2793 csr->next_top_at_mark_start(), | |
2794 csr->top_at_conc_mark_count(), | |
2795 csr->age_in_surv_rate_group_cond(), | |
2796 csr->is_young(), | |
2797 csr->is_survivor()); | |
2798 csr = next; | |
2799 } | |
2800 } | |
2801 #endif // !PRODUCT | |
2802 | |
2803 bool | |
2804 G1CollectorPolicy_BestRegionsFirst::choose_collection_set() { | |
2805 // Set this here - in case we're not doing young collections. | |
2806 double non_young_start_time_sec = os::elapsedTime(); | |
2807 | |
2808 // The result that this routine will return. This will be set to | |
2809 // false if: | |
2810 // * we're doing a young or partially young collection and we | |
2811 // have added the youg regions to collection set, or | |
2812 // * we add old regions to the collection set. | |
2813 bool abandon_collection = true; | |
2814 | |
2978 start_recording_regions(); | 2815 start_recording_regions(); |
2979 | 2816 |
2980 guarantee(_target_pause_time_ms > -1.0 | 2817 guarantee(_target_pause_time_ms > -1.0 |
2981 NOT_PRODUCT(|| Universe::heap()->gc_cause() == GCCause::_scavenge_alot), | 2818 NOT_PRODUCT(|| Universe::heap()->gc_cause() == GCCause::_scavenge_alot), |
2982 "_target_pause_time_ms should have been set!"); | 2819 "_target_pause_time_ms should have been set!"); |
3025 if (in_young_gc_mode()) { | 2862 if (in_young_gc_mode()) { |
3026 double young_start_time_sec = os::elapsedTime(); | 2863 double young_start_time_sec = os::elapsedTime(); |
3027 | 2864 |
3028 if (G1PolicyVerbose > 0) { | 2865 if (G1PolicyVerbose > 0) { |
3029 gclog_or_tty->print_cr("Adding %d young regions to the CSet", | 2866 gclog_or_tty->print_cr("Adding %d young regions to the CSet", |
3030 _g1->young_list_length()); | 2867 _g1->young_list()->length()); |
3031 } | 2868 } |
2869 | |
3032 _young_cset_length = 0; | 2870 _young_cset_length = 0; |
3033 _last_young_gc_full = full_young_gcs() ? true : false; | 2871 _last_young_gc_full = full_young_gcs() ? true : false; |
2872 | |
3034 if (_last_young_gc_full) | 2873 if (_last_young_gc_full) |
3035 ++_full_young_pause_num; | 2874 ++_full_young_pause_num; |
3036 else | 2875 else |
3037 ++_partial_young_pause_num; | 2876 ++_partial_young_pause_num; |
3038 hr = _g1->pop_region_from_young_list(); | 2877 |
2878 // The young list is laid with the survivor regions from the previous | |
2879 // pause are appended to the RHS of the young list, i.e. | |
2880 // [Newly Young Regions ++ Survivors from last pause]. | |
2881 | |
2882 hr = _g1->young_list()->first_survivor_region(); | |
3039 while (hr != NULL) { | 2883 while (hr != NULL) { |
3040 | 2884 assert(hr->is_survivor(), "badly formed young list"); |
3041 assert( hr->young_index_in_cset() == -1, "invariant" ); | 2885 hr->set_young(); |
3042 assert( hr->age_in_surv_rate_group() != -1, "invariant" ); | 2886 hr = hr->get_next_young_region(); |
3043 hr->set_young_index_in_cset((int) _young_cset_length); | 2887 } |
3044 | 2888 |
3045 ++_young_cset_length; | 2889 // Clear the fields that point to the survivor list - they are |
3046 double predicted_time_ms = predict_region_elapsed_time_ms(hr, true); | 2890 // all young now. |
3047 time_remaining_ms -= predicted_time_ms; | 2891 _g1->young_list()->clear_survivors(); |
3048 predicted_pause_time_ms += predicted_time_ms; | 2892 |
3049 assert(!hr->in_collection_set(), "invariant"); | 2893 if (_g1->mark_in_progress()) |
3050 add_to_collection_set(hr); | 2894 _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger); |
3051 record_cset_region(hr, true); | 2895 |
3052 max_live_bytes -= MIN2(hr->max_live_bytes(), max_live_bytes); | 2896 _young_cset_length = _inc_cset_young_index; |
3053 if (G1PolicyVerbose > 0) { | 2897 _collection_set = _inc_cset_head; |
3054 gclog_or_tty->print_cr(" Added [" PTR_FORMAT ", " PTR_FORMAT") to CS.", | 2898 _collection_set_size = _inc_cset_size; |
3055 hr->bottom(), hr->end()); | 2899 _collection_set_bytes_used_before = _inc_cset_bytes_used_before; |
3056 gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)", | 2900 |
3057 max_live_bytes/K); | 2901 // For young regions in the collection set, we assume the worst |
3058 } | 2902 // case of complete survival |
3059 hr = _g1->pop_region_from_young_list(); | 2903 max_live_bytes -= _inc_cset_size * HeapRegion::GrainBytes; |
3060 } | 2904 |
3061 | 2905 time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms; |
3062 record_scan_only_regions(_g1->young_list_scan_only_length()); | 2906 predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; |
2907 | |
2908 // The number of recorded young regions is the incremental | |
2909 // collection set's current size | |
2910 set_recorded_young_regions(_inc_cset_size); | |
2911 set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths); | |
2912 set_recorded_young_bytes(_inc_cset_recorded_young_bytes); | |
2913 #if PREDICTIONS_VERBOSE | |
2914 set_predicted_bytes_to_copy(_inc_cset_predicted_bytes_to_copy); | |
2915 #endif // PREDICTIONS_VERBOSE | |
2916 | |
2917 if (G1PolicyVerbose > 0) { | |
2918 gclog_or_tty->print_cr(" Added " PTR_FORMAT " Young Regions to CS.", | |
2919 _inc_cset_size); | |
2920 gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)", | |
2921 max_live_bytes/K); | |
2922 } | |
2923 | |
2924 assert(_inc_cset_size == _g1->young_list()->length(), "Invariant"); | |
2925 if (_inc_cset_size > 0) { | |
2926 assert(_collection_set != NULL, "Invariant"); | |
2927 abandon_collection = false; | |
2928 } | |
3063 | 2929 |
3064 double young_end_time_sec = os::elapsedTime(); | 2930 double young_end_time_sec = os::elapsedTime(); |
3065 _recorded_young_cset_choice_time_ms = | 2931 _recorded_young_cset_choice_time_ms = |
3066 (young_end_time_sec - young_start_time_sec) * 1000.0; | 2932 (young_end_time_sec - young_start_time_sec) * 1000.0; |
3067 | 2933 |
3068 non_young_start_time_sec = os::elapsedTime(); | 2934 // We are doing young collections so reset this. |
3069 | 2935 non_young_start_time_sec = young_end_time_sec; |
3070 if (_young_cset_length > 0 && _last_young_gc_full) { | 2936 |
2937 // Note we can use either _collection_set_size or | |
2938 // _young_cset_length here | |
2939 if (_collection_set_size > 0 && _last_young_gc_full) { | |
3071 // don't bother adding more regions... | 2940 // don't bother adding more regions... |
3072 goto choose_collection_set_end; | 2941 goto choose_collection_set_end; |
3073 } | 2942 } |
3074 } | 2943 } |
3075 | 2944 |
3076 if (!in_young_gc_mode() || !full_young_gcs()) { | 2945 if (!in_young_gc_mode() || !full_young_gcs()) { |
3077 bool should_continue = true; | 2946 bool should_continue = true; |
3078 NumberSeq seq; | 2947 NumberSeq seq; |
3079 double avg_prediction = 100000000000000000.0; // something very large | 2948 double avg_prediction = 100000000000000000.0; // something very large |
2949 | |
2950 // Save the current size of the collection set to detect | |
2951 // if we actually added any old regions. | |
2952 size_t n_young_regions = _collection_set_size; | |
2953 | |
3080 do { | 2954 do { |
3081 hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms, | 2955 hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms, |
3082 avg_prediction); | 2956 avg_prediction); |
3083 if (hr != NULL) { | 2957 if (hr != NULL) { |
3084 double predicted_time_ms = predict_region_elapsed_time_ms(hr, false); | 2958 double predicted_time_ms = predict_region_elapsed_time_ms(hr, false); |
3085 time_remaining_ms -= predicted_time_ms; | 2959 time_remaining_ms -= predicted_time_ms; |
3086 predicted_pause_time_ms += predicted_time_ms; | 2960 predicted_pause_time_ms += predicted_time_ms; |
3087 add_to_collection_set(hr); | 2961 add_to_collection_set(hr); |
3088 record_cset_region(hr, false); | 2962 record_non_young_cset_region(hr); |
3089 max_live_bytes -= MIN2(hr->max_live_bytes(), max_live_bytes); | 2963 max_live_bytes -= MIN2(hr->max_live_bytes(), max_live_bytes); |
3090 if (G1PolicyVerbose > 0) { | 2964 if (G1PolicyVerbose > 0) { |
3091 gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)", | 2965 gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)", |
3092 max_live_bytes/K); | 2966 max_live_bytes/K); |
3093 } | 2967 } |
3101 } while (should_continue); | 2975 } while (should_continue); |
3102 | 2976 |
3103 if (!adaptive_young_list_length() && | 2977 if (!adaptive_young_list_length() && |
3104 _collection_set_size < _young_list_fixed_length) | 2978 _collection_set_size < _young_list_fixed_length) |
3105 _should_revert_to_full_young_gcs = true; | 2979 _should_revert_to_full_young_gcs = true; |
2980 | |
2981 if (_collection_set_size > n_young_regions) { | |
2982 // We actually added old regions to the collection set | |
2983 // so we are not abandoning this collection. | |
2984 abandon_collection = false; | |
2985 } | |
3106 } | 2986 } |
3107 | 2987 |
3108 choose_collection_set_end: | 2988 choose_collection_set_end: |
2989 stop_incremental_cset_building(); | |
2990 | |
3109 count_CS_bytes_used(); | 2991 count_CS_bytes_used(); |
3110 | 2992 |
3111 end_recording_regions(); | 2993 end_recording_regions(); |
3112 | 2994 |
3113 double non_young_end_time_sec = os::elapsedTime(); | 2995 double non_young_end_time_sec = os::elapsedTime(); |
3114 _recorded_non_young_cset_choice_time_ms = | 2996 _recorded_non_young_cset_choice_time_ms = |
3115 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; | 2997 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; |
2998 | |
2999 return abandon_collection; | |
3116 } | 3000 } |
3117 | 3001 |
3118 void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() { | 3002 void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() { |
3119 G1CollectorPolicy::record_full_collection_end(); | 3003 G1CollectorPolicy::record_full_collection_end(); |
3120 _collectionSetChooser->updateAfterFullCollection(); | 3004 _collectionSetChooser->updateAfterFullCollection(); |