comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 3914:20213c8a3c40

7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions Summary: It introduces ergonomic decision logging in G1 for the following heuristics: heap sizing, collection set construction, concurrent cycle initiation, and partially-young GC start/end. The code has a bit of refactoring in a few places to make the decision logging possible. It also replaces alternative ad-hoc logging that we have under different parameters and switches (G1_DEBUG, G1PolicyVerbose). Reviewed-by: johnc, ysr
author tonyp
date Wed, 07 Sep 2011 12:21:23 -0400
parents ae73da50be4b
children 4f41766176cf
comparison
equal deleted inserted replaced
3913:27702f012017 3914:20213c8a3c40
26 #include "gc_implementation/g1/concurrentG1Refine.hpp" 26 #include "gc_implementation/g1/concurrentG1Refine.hpp"
27 #include "gc_implementation/g1/concurrentMark.hpp" 27 #include "gc_implementation/g1/concurrentMark.hpp"
28 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp" 28 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
30 #include "gc_implementation/g1/g1CollectorPolicy.hpp" 30 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
31 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
31 #include "gc_implementation/g1/heapRegionRemSet.hpp" 32 #include "gc_implementation/g1/heapRegionRemSet.hpp"
32 #include "gc_implementation/shared/gcPolicyCounters.hpp" 33 #include "gc_implementation/shared/gcPolicyCounters.hpp"
33 #include "runtime/arguments.hpp" 34 #include "runtime/arguments.hpp"
34 #include "runtime/java.hpp" 35 #include "runtime/java.hpp"
35 #include "runtime/mutexLocker.hpp" 36 #include "runtime/mutexLocker.hpp"
269 _recorded_survivor_regions(0), 270 _recorded_survivor_regions(0),
270 _recorded_survivor_head(NULL), 271 _recorded_survivor_head(NULL),
271 _recorded_survivor_tail(NULL), 272 _recorded_survivor_tail(NULL),
272 _survivors_age_table(true), 273 _survivors_age_table(true),
273 274
274 _gc_overhead_perc(0.0) 275 _gc_overhead_perc(0.0) {
275 276
276 {
277 // Set up the region size and associated fields. Given that the 277 // Set up the region size and associated fields. Given that the
278 // policy is created before the heap, we have to set this up here, 278 // policy is created before the heap, we have to set this up here,
279 // so it's done as soon as possible. 279 // so it's done as soon as possible.
280 HeapRegion::setup_heap_region_size(Arguments::min_heap_size()); 280 HeapRegion::setup_heap_region_size(Arguments::min_heap_size());
281 HeapRegionRemSet::setup_remset_size(); 281 HeapRegionRemSet::setup_remset_size();
282
283 G1ErgoVerbose::initialize();
284 if (PrintAdaptiveSizePolicy) {
285 // Currently, we only use a single switch for all the heuristics.
286 G1ErgoVerbose::set_enabled(true);
287 // Given that we don't currently have a verboseness level
288 // parameter, we'll hardcode this to high. This can be easily
289 // changed in the future.
290 G1ErgoVerbose::set_level(ErgoHigh);
291 } else {
292 G1ErgoVerbose::set_enabled(false);
293 }
282 294
283 // Verify PLAB sizes 295 // Verify PLAB sizes
284 const uint region_size = HeapRegion::GrainWords; 296 const uint region_size = HeapRegion::GrainWords;
285 if (YoungPLABSize > region_size || OldPLABSize > region_size) { 297 if (YoungPLABSize > region_size || OldPLABSize > region_size) {
286 char buffer[128]; 298 char buffer[128];
957 969
958 void 970 void
959 G1CollectorPolicy:: 971 G1CollectorPolicy::
960 record_concurrent_mark_cleanup_end_work1(size_t freed_bytes, 972 record_concurrent_mark_cleanup_end_work1(size_t freed_bytes,
961 size_t max_live_bytes) { 973 size_t max_live_bytes) {
962 if (_n_marks < 2) _n_marks++; 974 if (_n_marks < 2) {
963 if (G1PolicyVerbose > 0) 975 _n_marks++;
964 gclog_or_tty->print_cr("At end of marking, max_live is " SIZE_FORMAT " MB " 976 }
965 " (of " SIZE_FORMAT " MB heap).",
966 max_live_bytes/M, _g1->capacity()/M);
967 } 977 }
968 978
969 // The important thing about this is that it includes "os::elapsedTime". 979 // The important thing about this is that it includes "os::elapsedTime".
970 void G1CollectorPolicy::record_concurrent_mark_cleanup_end_work2() { 980 void G1CollectorPolicy::record_concurrent_mark_cleanup_end_work2() {
971 double end_time_sec = os::elapsedTime(); 981 double end_time_sec = os::elapsedTime();
975 _prev_collection_pause_end_ms += elapsed_time_ms; 985 _prev_collection_pause_end_ms += elapsed_time_ms;
976 986
977 _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_time_sec, true); 987 _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_time_sec, true);
978 988
979 _num_markings++; 989 _num_markings++;
980
981 // We did a marking, so reset the "since_last_mark" variables.
982 double considerConcMarkCost = 1.0;
983 // If there are available processors, concurrent activity is free...
984 if (Threads::number_of_non_daemon_threads() * 2 <
985 os::active_processor_count()) {
986 considerConcMarkCost = 0.0;
987 }
988 _n_pauses_at_mark_end = _n_pauses; 990 _n_pauses_at_mark_end = _n_pauses;
989 _n_marks_since_last_pause++; 991 _n_marks_since_last_pause++;
990 } 992 }
991 993
992 void 994 void
1146 1148
1147 last_pause_included_initial_mark = during_initial_mark_pause(); 1149 last_pause_included_initial_mark = during_initial_mark_pause();
1148 if (last_pause_included_initial_mark) 1150 if (last_pause_included_initial_mark)
1149 record_concurrent_mark_init_end(0.0); 1151 record_concurrent_mark_init_end(0.0);
1150 1152
1151 size_t min_used_targ = 1153 size_t marking_initiating_used_threshold =
1152 (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent; 1154 (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent;
1153
1154 1155
1155 if (!_g1->mark_in_progress() && !_last_full_young_gc) { 1156 if (!_g1->mark_in_progress() && !_last_full_young_gc) {
1156 assert(!last_pause_included_initial_mark, "invariant"); 1157 assert(!last_pause_included_initial_mark, "invariant");
1157 if (cur_used_bytes > min_used_targ && 1158 if (cur_used_bytes > marking_initiating_used_threshold) {
1158 cur_used_bytes > _prev_collection_pause_used_at_end_bytes) { 1159 if (cur_used_bytes > _prev_collection_pause_used_at_end_bytes) {
1159 assert(!during_initial_mark_pause(), "we should not see this here"); 1160 assert(!during_initial_mark_pause(), "we should not see this here");
1161
1162 ergo_verbose3(ErgoConcCycles,
1163 "request concurrent cycle initiation",
1164 ergo_format_reason("occupancy higher than threshold")
1165 ergo_format_byte("occupancy")
1166 ergo_format_byte_perc("threshold"),
1167 cur_used_bytes,
1168 marking_initiating_used_threshold,
1169 (double) InitiatingHeapOccupancyPercent);
1160 1170
1161 // Note: this might have already been set, if during the last 1171 // Note: this might have already been set, if during the last
1162 // pause we decided to start a cycle but at the beginning of 1172 // pause we decided to start a cycle but at the beginning of
1163 // this pause we decided to postpone it. That's OK. 1173 // this pause we decided to postpone it. That's OK.
1164 set_initiate_conc_mark_if_possible(); 1174 set_initiate_conc_mark_if_possible();
1175 } else {
1176 ergo_verbose2(ErgoConcCycles,
1177 "do not request concurrent cycle initiation",
1178 ergo_format_reason("occupancy lower than previous occupancy")
1179 ergo_format_byte("occupancy")
1180 ergo_format_byte("previous occupancy"),
1181 cur_used_bytes,
1182 _prev_collection_pause_used_at_end_bytes);
1183 }
1165 } 1184 }
1166 } 1185 }
1167 1186
1168 _prev_collection_pause_used_at_end_bytes = cur_used_bytes; 1187 _prev_collection_pause_used_at_end_bytes = cur_used_bytes;
1169 1188
1435 new_in_marking_window = true; 1454 new_in_marking_window = true;
1436 new_in_marking_window_im = true; 1455 new_in_marking_window_im = true;
1437 } 1456 }
1438 1457
1439 if (_last_full_young_gc) { 1458 if (_last_full_young_gc) {
1459 ergo_verbose2(ErgoPartiallyYoungGCs,
1460 "start partially-young GCs",
1461 ergo_format_byte_perc("known garbage"),
1462 _known_garbage_bytes, _known_garbage_ratio * 100.0);
1440 set_full_young_gcs(false); 1463 set_full_young_gcs(false);
1441 _last_full_young_gc = false; 1464 _last_full_young_gc = false;
1442 } 1465 }
1443 1466
1444 if ( !_last_young_gc_full ) { 1467 if ( !_last_young_gc_full ) {
1445 if ( _should_revert_to_full_young_gcs || 1468 if (_should_revert_to_full_young_gcs) {
1446 _known_garbage_ratio < 0.05 || 1469 ergo_verbose2(ErgoPartiallyYoungGCs,
1447 (adaptive_young_list_length() && 1470 "end partially-young GCs",
1448 (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) ) { 1471 ergo_format_reason("partially-young GCs end requested")
1449 set_full_young_gcs(true); 1472 ergo_format_byte_perc("known garbage"),
1473 _known_garbage_bytes, _known_garbage_ratio * 100.0);
1474 set_full_young_gcs(true);
1475 } else if (_known_garbage_ratio < 0.05) {
1476 ergo_verbose3(ErgoPartiallyYoungGCs,
1477 "end partially-young GCs",
1478 ergo_format_reason("known garbage percent lower than threshold")
1479 ergo_format_byte_perc("known garbage")
1480 ergo_format_perc("threshold"),
1481 _known_garbage_bytes, _known_garbage_ratio * 100.0,
1482 0.05 * 100.0);
1483 set_full_young_gcs(true);
1484 } else if (adaptive_young_list_length() &&
1485 (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) {
1486 ergo_verbose5(ErgoPartiallyYoungGCs,
1487 "end partially-young GCs",
1488 ergo_format_reason("current GC efficiency lower than "
1489 "predicted fully-young GC efficiency")
1490 ergo_format_double("GC efficiency factor")
1491 ergo_format_double("current GC efficiency")
1492 ergo_format_double("predicted fully-young GC efficiency")
1493 ergo_format_byte_perc("known garbage"),
1494 get_gc_eff_factor(), cur_efficiency,
1495 predict_young_gc_eff(),
1496 _known_garbage_bytes, _known_garbage_ratio * 100.0);
1497 set_full_young_gcs(true);
1450 } 1498 }
1451 } 1499 }
1452 _should_revert_to_full_young_gcs = false; 1500 _should_revert_to_full_young_gcs = false;
1453 1501
1454 if (_last_young_gc_full && !_during_marking) { 1502 if (_last_young_gc_full && !_during_marking) {
1875 void G1CollectorPolicy::check_if_region_is_too_expensive(double 1923 void G1CollectorPolicy::check_if_region_is_too_expensive(double
1876 predicted_time_ms) { 1924 predicted_time_ms) {
1877 // I don't think we need to do this when in young GC mode since 1925 // I don't think we need to do this when in young GC mode since
1878 // marking will be initiated next time we hit the soft limit anyway... 1926 // marking will be initiated next time we hit the soft limit anyway...
1879 if (predicted_time_ms > _expensive_region_limit_ms) { 1927 if (predicted_time_ms > _expensive_region_limit_ms) {
1928 ergo_verbose2(ErgoPartiallyYoungGCs,
1929 "request partially-young GCs end",
1930 ergo_format_reason("predicted region time higher than threshold")
1931 ergo_format_ms("predicted region time")
1932 ergo_format_ms("threshold"),
1933 predicted_time_ms, _expensive_region_limit_ms);
1880 // no point in doing another partial one 1934 // no point in doing another partial one
1881 _should_revert_to_full_young_gcs = true; 1935 _should_revert_to_full_young_gcs = true;
1882 } 1936 }
1883 } 1937 }
1884 1938
1984 res = MIN2(res, 1.0); 2038 res = MIN2(res, 1.0);
1985 return res; 2039 return res;
1986 } 2040 }
1987 2041
1988 size_t G1CollectorPolicy::expansion_amount() { 2042 size_t G1CollectorPolicy::expansion_amount() {
1989 if ((recent_avg_pause_time_ratio() * 100.0) > _gc_overhead_perc) { 2043 double recent_gc_overhead = recent_avg_pause_time_ratio() * 100.0;
2044 double threshold = _gc_overhead_perc;
2045 if (recent_gc_overhead > threshold) {
1990 // We will double the existing space, or take 2046 // We will double the existing space, or take
1991 // G1ExpandByPercentOfAvailable % of the available expansion 2047 // G1ExpandByPercentOfAvailable % of the available expansion
1992 // space, whichever is smaller, bounded below by a minimum 2048 // space, whichever is smaller, bounded below by a minimum
1993 // expansion (unless that's all that's left.) 2049 // expansion (unless that's all that's left.)
1994 const size_t min_expand_bytes = 1*M; 2050 const size_t min_expand_bytes = 1*M;
1999 size_t expand_bytes_via_pct = 2055 size_t expand_bytes_via_pct =
2000 uncommitted_bytes * G1ExpandByPercentOfAvailable / 100; 2056 uncommitted_bytes * G1ExpandByPercentOfAvailable / 100;
2001 expand_bytes = MIN2(expand_bytes_via_pct, committed_bytes); 2057 expand_bytes = MIN2(expand_bytes_via_pct, committed_bytes);
2002 expand_bytes = MAX2(expand_bytes, min_expand_bytes); 2058 expand_bytes = MAX2(expand_bytes, min_expand_bytes);
2003 expand_bytes = MIN2(expand_bytes, uncommitted_bytes); 2059 expand_bytes = MIN2(expand_bytes, uncommitted_bytes);
2004 if (G1PolicyVerbose > 1) { 2060
2005 gclog_or_tty->print("Decided to expand: ratio = %5.2f, " 2061 ergo_verbose5(ErgoHeapSizing,
2006 "committed = %d%s, uncommited = %d%s, via pct = %d%s.\n" 2062 "attempt heap expansion",
2007 " Answer = %d.\n", 2063 ergo_format_reason("recent GC overhead higher than "
2008 recent_avg_pause_time_ratio(), 2064 "threshold after GC")
2009 byte_size_in_proper_unit(committed_bytes), 2065 ergo_format_perc("recent GC overhead")
2010 proper_unit_for_byte_size(committed_bytes), 2066 ergo_format_perc("threshold")
2011 byte_size_in_proper_unit(uncommitted_bytes), 2067 ergo_format_byte("uncommitted")
2012 proper_unit_for_byte_size(uncommitted_bytes), 2068 ergo_format_byte_perc("calculated expansion amount"),
2013 byte_size_in_proper_unit(expand_bytes_via_pct), 2069 recent_gc_overhead, threshold,
2014 proper_unit_for_byte_size(expand_bytes_via_pct), 2070 uncommitted_bytes,
2015 byte_size_in_proper_unit(expand_bytes), 2071 expand_bytes_via_pct, (double) G1ExpandByPercentOfAvailable);
2016 proper_unit_for_byte_size(expand_bytes)); 2072
2017 }
2018 return expand_bytes; 2073 return expand_bytes;
2019 } else { 2074 } else {
2020 return 0; 2075 return 0;
2021 } 2076 }
2022 } 2077 }
2235 _short_lived_surv_rate_group->print_surv_rate_summary(); 2290 _short_lived_surv_rate_group->print_surv_rate_summary();
2236 // add this call for any other surv rate groups 2291 // add this call for any other surv rate groups
2237 #endif // PRODUCT 2292 #endif // PRODUCT
2238 } 2293 }
2239 2294
2240 void 2295 void G1CollectorPolicy::update_region_num(bool young) {
2241 G1CollectorPolicy::update_region_num(bool young) {
2242 if (young) { 2296 if (young) {
2243 ++_region_num_young; 2297 ++_region_num_young;
2244 } else { 2298 } else {
2245 ++_region_num_tenured; 2299 ++_region_num_tenured;
2246 } 2300 }
2313 _g1->heap_region_iterate(&cl); 2367 _g1->heap_region_iterate(&cl);
2314 return true; 2368 return true;
2315 } 2369 }
2316 #endif 2370 #endif
2317 2371
2318 bool 2372 bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(
2319 G1CollectorPolicy::force_initial_mark_if_outside_cycle() { 2373 GCCause::Cause gc_cause) {
2320 bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle(); 2374 bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
2321 if (!during_cycle) { 2375 if (!during_cycle) {
2376 ergo_verbose1(ErgoConcCycles,
2377 "request concurrent cycle initiation",
2378 ergo_format_reason("requested by GC cause")
2379 ergo_format_str("GC cause"),
2380 GCCause::to_string(gc_cause));
2322 set_initiate_conc_mark_if_possible(); 2381 set_initiate_conc_mark_if_possible();
2323 return true; 2382 return true;
2324 } else { 2383 } else {
2384 ergo_verbose1(ErgoConcCycles,
2385 "do not request concurrent cycle initiation",
2386 ergo_format_reason("concurrent cycle already in progress")
2387 ergo_format_str("GC cause"),
2388 GCCause::to_string(gc_cause));
2325 return false; 2389 return false;
2326 } 2390 }
2327 } 2391 }
2328 2392
2329 void 2393 void
2351 set_during_initial_mark_pause(); 2415 set_during_initial_mark_pause();
2352 2416
2353 // And we can now clear initiate_conc_mark_if_possible() as 2417 // And we can now clear initiate_conc_mark_if_possible() as
2354 // we've already acted on it. 2418 // we've already acted on it.
2355 clear_initiate_conc_mark_if_possible(); 2419 clear_initiate_conc_mark_if_possible();
2420
2421 ergo_verbose0(ErgoConcCycles,
2422 "initiate concurrent cycle",
2423 ergo_format_reason("concurrent cycle initiation requested"));
2356 } else { 2424 } else {
2357 // The concurrent marking thread is still finishing up the 2425 // The concurrent marking thread is still finishing up the
2358 // previous cycle. If we start one right now the two cycles 2426 // previous cycle. If we start one right now the two cycles
2359 // overlap. In particular, the concurrent marking thread might 2427 // overlap. In particular, the concurrent marking thread might
2360 // be in the process of clearing the next marking bitmap (which 2428 // be in the process of clearing the next marking bitmap (which
2364 // cannot wait for the marking thread to finish the cycle as it 2432 // cannot wait for the marking thread to finish the cycle as it
2365 // periodically yields while clearing the next marking bitmap 2433 // periodically yields while clearing the next marking bitmap
2366 // and, if it's in a yield point, it's waiting for us to 2434 // and, if it's in a yield point, it's waiting for us to
2367 // finish. So, at this point we will not start a cycle and we'll 2435 // finish. So, at this point we will not start a cycle and we'll
2368 // let the concurrent marking thread complete the last one. 2436 // let the concurrent marking thread complete the last one.
2437 ergo_verbose0(ErgoConcCycles,
2438 "do not initiate concurrent cycle",
2439 ergo_format_reason("concurrent cycle already in progress"));
2369 } 2440 }
2370 } 2441 }
2371 } 2442 }
2372 2443
2373 void 2444 void
2754 G1CollectorPolicy_BestRegionsFirst::choose_collection_set( 2825 G1CollectorPolicy_BestRegionsFirst::choose_collection_set(
2755 double target_pause_time_ms) { 2826 double target_pause_time_ms) {
2756 // Set this here - in case we're not doing young collections. 2827 // Set this here - in case we're not doing young collections.
2757 double non_young_start_time_sec = os::elapsedTime(); 2828 double non_young_start_time_sec = os::elapsedTime();
2758 2829
2830 YoungList* young_list = _g1->young_list();
2831
2759 start_recording_regions(); 2832 start_recording_regions();
2760 2833
2761 guarantee(target_pause_time_ms > 0.0, 2834 guarantee(target_pause_time_ms > 0.0,
2762 err_msg("target_pause_time_ms = %1.6lf should be positive", 2835 err_msg("target_pause_time_ms = %1.6lf should be positive",
2763 target_pause_time_ms)); 2836 target_pause_time_ms));
2766 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); 2839 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
2767 double predicted_pause_time_ms = base_time_ms; 2840 double predicted_pause_time_ms = base_time_ms;
2768 2841
2769 double time_remaining_ms = target_pause_time_ms - base_time_ms; 2842 double time_remaining_ms = target_pause_time_ms - base_time_ms;
2770 2843
2844 ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
2845 "start choosing CSet",
2846 ergo_format_ms("predicted base time")
2847 ergo_format_ms("remaining time")
2848 ergo_format_ms("target pause time"),
2849 base_time_ms, time_remaining_ms, target_pause_time_ms);
2850
2771 // the 10% and 50% values are arbitrary... 2851 // the 10% and 50% values are arbitrary...
2772 if (time_remaining_ms < 0.10 * target_pause_time_ms) { 2852 double threshold = 0.10 * target_pause_time_ms;
2853 if (time_remaining_ms < threshold) {
2854 double prev_time_remaining_ms = time_remaining_ms;
2773 time_remaining_ms = 0.50 * target_pause_time_ms; 2855 time_remaining_ms = 0.50 * target_pause_time_ms;
2774 _within_target = false; 2856 _within_target = false;
2857 ergo_verbose3(ErgoCSetConstruction,
2858 "adjust remaining time",
2859 ergo_format_reason("remaining time lower than threshold")
2860 ergo_format_ms("remaining time")
2861 ergo_format_ms("threshold")
2862 ergo_format_ms("adjusted remaining time"),
2863 prev_time_remaining_ms, threshold, time_remaining_ms);
2775 } else { 2864 } else {
2776 _within_target = true; 2865 _within_target = true;
2777 } 2866 }
2778 2867
2779 // We figure out the number of bytes available for future to-space. 2868 size_t expansion_bytes = _g1->expansion_regions() * HeapRegion::GrainBytes;
2780 // For new regions without marking information, we must assume the 2869
2781 // worst-case of complete survival. If we have marking information for a 2870 HeapRegion* hr;
2782 // region, we can bound the amount of live data. We can add a number of 2871 double young_start_time_sec = os::elapsedTime();
2783 // such regions, as long as the sum of the live data bounds does not
2784 // exceed the available evacuation space.
2785 size_t max_live_bytes = _g1->free_regions() * HeapRegion::GrainBytes;
2786
2787 size_t expansion_bytes =
2788 _g1->expansion_regions() * HeapRegion::GrainBytes;
2789 2872
2790 _collection_set_bytes_used_before = 0; 2873 _collection_set_bytes_used_before = 0;
2791 _collection_set_size = 0; 2874 _collection_set_size = 0;
2792
2793 // Adjust for expansion and slop.
2794 max_live_bytes = max_live_bytes + expansion_bytes;
2795
2796 HeapRegion* hr;
2797 double young_start_time_sec = os::elapsedTime();
2798
2799 if (G1PolicyVerbose > 0) {
2800 gclog_or_tty->print_cr("Adding %d young regions to the CSet",
2801 _g1->young_list()->length());
2802 }
2803
2804 _young_cset_length = 0; 2875 _young_cset_length = 0;
2805 _last_young_gc_full = full_young_gcs() ? true : false; 2876 _last_young_gc_full = full_young_gcs() ? true : false;
2806 2877
2807 if (_last_young_gc_full) 2878 if (_last_young_gc_full) {
2808 ++_full_young_pause_num; 2879 ++_full_young_pause_num;
2809 else 2880 } else {
2810 ++_partial_young_pause_num; 2881 ++_partial_young_pause_num;
2882 }
2811 2883
2812 // The young list is laid with the survivor regions from the previous 2884 // The young list is laid with the survivor regions from the previous
2813 // pause are appended to the RHS of the young list, i.e. 2885 // pause are appended to the RHS of the young list, i.e.
2814 // [Newly Young Regions ++ Survivors from last pause]. 2886 // [Newly Young Regions ++ Survivors from last pause].
2815 2887
2816 hr = _g1->young_list()->first_survivor_region(); 2888 size_t survivor_region_num = young_list->survivor_length();
2889 size_t eden_region_num = young_list->length() - survivor_region_num;
2890 size_t old_region_num = 0;
2891 hr = young_list->first_survivor_region();
2817 while (hr != NULL) { 2892 while (hr != NULL) {
2818 assert(hr->is_survivor(), "badly formed young list"); 2893 assert(hr->is_survivor(), "badly formed young list");
2819 hr->set_young(); 2894 hr->set_young();
2820 hr = hr->get_next_young_region(); 2895 hr = hr->get_next_young_region();
2821 } 2896 }
2822 2897
2823 // Clear the fields that point to the survivor list - they are 2898 // Clear the fields that point to the survivor list - they are all young now.
2824 // all young now. 2899 young_list->clear_survivors();
2825 _g1->young_list()->clear_survivors();
2826 2900
2827 if (_g1->mark_in_progress()) 2901 if (_g1->mark_in_progress())
2828 _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger); 2902 _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger);
2829 2903
2830 _young_cset_length = _inc_cset_young_index; 2904 _young_cset_length = _inc_cset_young_index;
2831 _collection_set = _inc_cset_head; 2905 _collection_set = _inc_cset_head;
2832 _collection_set_size = _inc_cset_size; 2906 _collection_set_size = _inc_cset_size;
2833 _collection_set_bytes_used_before = _inc_cset_bytes_used_before; 2907 _collection_set_bytes_used_before = _inc_cset_bytes_used_before;
2834
2835 // For young regions in the collection set, we assume the worst
2836 // case of complete survival
2837 max_live_bytes -= _inc_cset_size * HeapRegion::GrainBytes;
2838
2839 time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms; 2908 time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms;
2840 predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; 2909 predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms;
2910
2911 ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
2912 "add young regions to CSet",
2913 ergo_format_region("eden")
2914 ergo_format_region("survivors")
2915 ergo_format_ms("predicted young region time"),
2916 eden_region_num, survivor_region_num,
2917 _inc_cset_predicted_elapsed_time_ms);
2841 2918
2842 // The number of recorded young regions is the incremental 2919 // The number of recorded young regions is the incremental
2843 // collection set's current size 2920 // collection set's current size
2844 set_recorded_young_regions(_inc_cset_size); 2921 set_recorded_young_regions(_inc_cset_size);
2845 set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths); 2922 set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths);
2846 set_recorded_young_bytes(_inc_cset_recorded_young_bytes); 2923 set_recorded_young_bytes(_inc_cset_recorded_young_bytes);
2847 #if PREDICTIONS_VERBOSE 2924 #if PREDICTIONS_VERBOSE
2848 set_predicted_bytes_to_copy(_inc_cset_predicted_bytes_to_copy); 2925 set_predicted_bytes_to_copy(_inc_cset_predicted_bytes_to_copy);
2849 #endif // PREDICTIONS_VERBOSE 2926 #endif // PREDICTIONS_VERBOSE
2850 2927
2851 if (G1PolicyVerbose > 0) { 2928 assert(_inc_cset_size == young_list->length(), "Invariant");
2852 gclog_or_tty->print_cr(" Added " PTR_FORMAT " Young Regions to CS.",
2853 _inc_cset_size);
2854 gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)",
2855 max_live_bytes/K);
2856 }
2857
2858 assert(_inc_cset_size == _g1->young_list()->length(), "Invariant");
2859 2929
2860 double young_end_time_sec = os::elapsedTime(); 2930 double young_end_time_sec = os::elapsedTime();
2861 _recorded_young_cset_choice_time_ms = 2931 _recorded_young_cset_choice_time_ms =
2862 (young_end_time_sec - young_start_time_sec) * 1000.0; 2932 (young_end_time_sec - young_start_time_sec) * 1000.0;
2863 2933
2867 if (!full_young_gcs()) { 2937 if (!full_young_gcs()) {
2868 bool should_continue = true; 2938 bool should_continue = true;
2869 NumberSeq seq; 2939 NumberSeq seq;
2870 double avg_prediction = 100000000000000000.0; // something very large 2940 double avg_prediction = 100000000000000000.0; // something very large
2871 2941
2942 size_t prev_collection_set_size = _collection_set_size;
2943 double prev_predicted_pause_time_ms = predicted_pause_time_ms;
2872 do { 2944 do {
2873 hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms, 2945 hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms,
2874 avg_prediction); 2946 avg_prediction);
2875 if (hr != NULL) { 2947 if (hr != NULL) {
2876 double predicted_time_ms = predict_region_elapsed_time_ms(hr, false); 2948 double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
2877 time_remaining_ms -= predicted_time_ms; 2949 time_remaining_ms -= predicted_time_ms;
2878 predicted_pause_time_ms += predicted_time_ms; 2950 predicted_pause_time_ms += predicted_time_ms;
2879 add_to_collection_set(hr); 2951 add_to_collection_set(hr);
2880 record_non_young_cset_region(hr); 2952 record_non_young_cset_region(hr);
2881 max_live_bytes -= MIN2(hr->max_live_bytes(), max_live_bytes);
2882 if (G1PolicyVerbose > 0) {
2883 gclog_or_tty->print_cr(" (" SIZE_FORMAT " KB left in heap.)",
2884 max_live_bytes/K);
2885 }
2886 seq.add(predicted_time_ms); 2953 seq.add(predicted_time_ms);
2887 avg_prediction = seq.avg() + seq.sd(); 2954 avg_prediction = seq.avg() + seq.sd();
2888 } 2955 }
2889 should_continue = 2956
2890 ( hr != NULL) && 2957 should_continue = true;
2891 ( (adaptive_young_list_length()) ? time_remaining_ms > 0.0 2958 if (hr == NULL) {
2892 : _collection_set_size < _young_list_fixed_length ); 2959 // No need for an ergo verbose message here,
2960 // getNextMarkRegion() does this when it returns NULL.
2961 should_continue = false;
2962 } else {
2963 if (adaptive_young_list_length()) {
2964 if (time_remaining_ms < 0.0) {
2965 ergo_verbose1(ErgoCSetConstruction,
2966 "stop adding old regions to CSet",
2967 ergo_format_reason("remaining time is lower than 0")
2968 ergo_format_ms("remaining time"),
2969 time_remaining_ms);
2970 should_continue = false;
2971 }
2972 } else {
2973 if (_collection_set_size < _young_list_fixed_length) {
2974 ergo_verbose2(ErgoCSetConstruction,
2975 "stop adding old regions to CSet",
2976 ergo_format_reason("CSet length lower than target")
2977 ergo_format_region("CSet")
2978 ergo_format_region("young target"),
2979 _collection_set_size, _young_list_fixed_length);
2980 should_continue = false;
2981 }
2982 }
2983 }
2893 } while (should_continue); 2984 } while (should_continue);
2894 2985
2895 if (!adaptive_young_list_length() && 2986 if (!adaptive_young_list_length() &&
2896 _collection_set_size < _young_list_fixed_length) 2987 _collection_set_size < _young_list_fixed_length) {
2988 ergo_verbose2(ErgoCSetConstruction,
2989 "request partially-young GCs end",
2990 ergo_format_reason("CSet length lower than target")
2991 ergo_format_region("CSet")
2992 ergo_format_region("young target"),
2993 _collection_set_size, _young_list_fixed_length);
2897 _should_revert_to_full_young_gcs = true; 2994 _should_revert_to_full_young_gcs = true;
2995 }
2996
2997 old_region_num = _collection_set_size - prev_collection_set_size;
2998
2999 ergo_verbose2(ErgoCSetConstruction | ErgoHigh,
3000 "add old regions to CSet",
3001 ergo_format_region("old")
3002 ergo_format_ms("predicted old region time"),
3003 old_region_num,
3004 predicted_pause_time_ms - prev_predicted_pause_time_ms);
2898 } 3005 }
2899 3006
2900 stop_incremental_cset_building(); 3007 stop_incremental_cset_building();
2901 3008
2902 count_CS_bytes_used(); 3009 count_CS_bytes_used();
2903 3010
2904 end_recording_regions(); 3011 end_recording_regions();
3012
3013 ergo_verbose5(ErgoCSetConstruction,
3014 "finish choosing CSet",
3015 ergo_format_region("eden")
3016 ergo_format_region("survivors")
3017 ergo_format_region("old")
3018 ergo_format_ms("predicted pause time")
3019 ergo_format_ms("target pause time"),
3020 eden_region_num, survivor_region_num, old_region_num,
3021 predicted_pause_time_ms, target_pause_time_ms);
2905 3022
2906 double non_young_end_time_sec = os::elapsedTime(); 3023 double non_young_end_time_sec = os::elapsedTime();
2907 _recorded_non_young_cset_choice_time_ms = 3024 _recorded_non_young_cset_choice_time_ms =
2908 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0; 3025 (non_young_end_time_sec - non_young_start_time_sec) * 1000.0;
2909 } 3026 }
2910 3027
2911 void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() { 3028 void G1CollectorPolicy_BestRegionsFirst::record_full_collection_end() {
2912 G1CollectorPolicy::record_full_collection_end(); 3029 G1CollectorPolicy::record_full_collection_end();
2913 _collectionSetChooser->updateAfterFullCollection(); 3030 _collectionSetChooser->updateAfterFullCollection();
2914 }
2915
2916 void G1CollectorPolicy_BestRegionsFirst::
2917 expand_if_possible(size_t numRegions) {
2918 size_t expansion_bytes = numRegions * HeapRegion::GrainBytes;
2919 _g1->expand(expansion_bytes);
2920 } 3031 }
2921 3032
2922 void G1CollectorPolicy_BestRegionsFirst:: 3033 void G1CollectorPolicy_BestRegionsFirst::
2923 record_collection_pause_end() { 3034 record_collection_pause_end() {
2924 G1CollectorPolicy::record_collection_pause_end(); 3035 G1CollectorPolicy::record_collection_pause_end();