comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 6611:7383557659bd

7185699: G1: Prediction model discrepancies Summary: Correct the result value of G1CollectedHeap::pending_card_num(). Change the code that calculates the GC efficiency of a non-young heap region to use historical data from mixed GCs and the actual number of live bytes when predicting how long it would take to collect the region. Changes were also reviewed by Thomas Schatzl. Reviewed-by: azeemj, brutisso
author johnc
date Tue, 21 Aug 2012 14:10:39 -0700
parents a2f7274eb6ef
children bb3f6194fedb
comparison
equal deleted inserted replaced
6610:f99a36499b8c 6611:7383557659bd
88 _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), 88 _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
89 _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)), 89 _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
90 90
91 _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), 91 _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
92 _prev_collection_pause_end_ms(0.0), 92 _prev_collection_pause_end_ms(0.0),
93 _pending_card_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
94 _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)), 93 _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
95 _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)), 94 _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
96 _young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)), 95 _young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
97 _mixed_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)), 96 _mixed_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
98 _cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)), 97 _cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
195 194
196 _phase_times = new G1GCPhaseTimes(_parallel_gc_threads); 195 _phase_times = new G1GCPhaseTimes(_parallel_gc_threads);
197 196
198 int index = MIN2(_parallel_gc_threads - 1, 7); 197 int index = MIN2(_parallel_gc_threads - 1, 7);
199 198
200 _pending_card_diff_seq->add(0.0);
201 _rs_length_diff_seq->add(rs_length_diff_defaults[index]); 199 _rs_length_diff_seq->add(rs_length_diff_defaults[index]);
202 _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]); 200 _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]);
203 _young_cards_per_entry_ratio_seq->add( 201 _young_cards_per_entry_ratio_seq->add(
204 young_cards_per_entry_ratio_defaults[index]); 202 young_cards_per_entry_ratio_defaults[index]);
205 _cost_per_entry_ms_seq->add(cost_per_entry_ms_defaults[index]); 203 _cost_per_entry_ms_seq->add(cost_per_entry_ms_defaults[index]);
655 double G1CollectorPolicy::predict_survivor_regions_evac_time() { 653 double G1CollectorPolicy::predict_survivor_regions_evac_time() {
656 double survivor_regions_evac_time = 0.0; 654 double survivor_regions_evac_time = 0.0;
657 for (HeapRegion * r = _recorded_survivor_head; 655 for (HeapRegion * r = _recorded_survivor_head;
658 r != NULL && r != _recorded_survivor_tail->get_next_young_region(); 656 r != NULL && r != _recorded_survivor_tail->get_next_young_region();
659 r = r->get_next_young_region()) { 657 r = r->get_next_young_region()) {
660 survivor_regions_evac_time += predict_region_elapsed_time_ms(r, true); 658 survivor_regions_evac_time += predict_region_elapsed_time_ms(r, gcs_are_young());
661 } 659 }
662 return survivor_regions_evac_time; 660 return survivor_regions_evac_time;
663 } 661 }
664 662
665 void G1CollectorPolicy::revise_young_list_target_length_if_necessary() { 663 void G1CollectorPolicy::revise_young_list_target_length_if_necessary() {
799 797
800 phase_times()->_cur_collection_start_sec = start_time_sec; 798 phase_times()->_cur_collection_start_sec = start_time_sec;
801 _cur_collection_pause_used_at_start_bytes = start_used; 799 _cur_collection_pause_used_at_start_bytes = start_used;
802 _cur_collection_pause_used_regions_at_start = _g1->used_regions(); 800 _cur_collection_pause_used_regions_at_start = _g1->used_regions();
803 _pending_cards = _g1->pending_card_num(); 801 _pending_cards = _g1->pending_card_num();
804 _max_pending_cards = _g1->max_pending_card_num(); 802
805 803 _collection_set_bytes_used_before = 0;
806 _bytes_in_collection_set_before_gc = 0;
807 _bytes_copied_during_gc = 0; 804 _bytes_copied_during_gc = 0;
808 805
809 YoungList* young_list = _g1->young_list(); 806 YoungList* young_list = _g1->young_list();
810 _eden_bytes_before_gc = young_list->eden_used_bytes(); 807 _eden_bytes_before_gc = young_list->eden_used_bytes();
811 _survivor_bytes_before_gc = young_list->survivor_used_bytes(); 808 _survivor_bytes_before_gc = young_list->survivor_used_bytes();
1034 1031
1035 _short_lived_surv_rate_group->start_adding_regions(); 1032 _short_lived_surv_rate_group->start_adding_regions();
1036 // do that for any other surv rate groupsx 1033 // do that for any other surv rate groupsx
1037 1034
1038 if (update_stats) { 1035 if (update_stats) {
1039 size_t diff = 0;
1040 if (_max_pending_cards >= _pending_cards) {
1041 diff = _max_pending_cards - _pending_cards;
1042 }
1043 _pending_card_diff_seq->add((double) diff);
1044
1045 double cost_per_card_ms = 0.0; 1036 double cost_per_card_ms = 0.0;
1046 if (_pending_cards > 0) { 1037 if (_pending_cards > 0) {
1047 cost_per_card_ms = phase_times()->_update_rs_time / (double) _pending_cards; 1038 cost_per_card_ms = phase_times()->_update_rs_time / (double) _pending_cards;
1048 _cost_per_card_ms_seq->add(cost_per_card_ms); 1039 _cost_per_card_ms_seq->add(cost_per_card_ms);
1049 } 1040 }
1124 double constant_other_time_ms = all_other_time_ms - 1115 double constant_other_time_ms = all_other_time_ms -
1125 (young_other_time_ms + non_young_other_time_ms); 1116 (young_other_time_ms + non_young_other_time_ms);
1126 _constant_other_time_ms_seq->add(constant_other_time_ms); 1117 _constant_other_time_ms_seq->add(constant_other_time_ms);
1127 1118
1128 double survival_ratio = 0.0; 1119 double survival_ratio = 0.0;
1129 if (_bytes_in_collection_set_before_gc > 0) { 1120 if (_collection_set_bytes_used_before > 0) {
1130 survival_ratio = (double) _bytes_copied_during_gc / 1121 survival_ratio = (double) _bytes_copied_during_gc /
1131 (double) _bytes_in_collection_set_before_gc; 1122 (double) _collection_set_bytes_used_before;
1132 } 1123 }
1133 1124
1134 _pending_cards_seq->add((double) _pending_cards); 1125 _pending_cards_seq->add((double) _pending_cards);
1135 _rs_lengths_seq->add((double) _max_rs_lengths); 1126 _rs_lengths_seq->add((double) _max_rs_lengths);
1136 } 1127 }
1227 } 1218 }
1228 dcqs.notify_if_necessary(); 1219 dcqs.notify_if_necessary();
1229 } 1220 }
1230 1221
1231 double 1222 double
1223 G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards,
1224 size_t scanned_cards) {
1225 return
1226 predict_rs_update_time_ms(pending_cards) +
1227 predict_rs_scan_time_ms(scanned_cards) +
1228 predict_constant_other_time_ms();
1229 }
1230
1231 double
1232 G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards) { 1232 G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards) {
1233 size_t rs_length = predict_rs_length_diff(); 1233 size_t rs_length = predict_rs_length_diff();
1234 size_t card_num; 1234 size_t card_num;
1235 if (gcs_are_young()) { 1235 if (gcs_are_young()) {
1236 card_num = predict_young_card_num(rs_length); 1236 card_num = predict_young_card_num(rs_length);
1237 } else { 1237 } else {
1238 card_num = predict_non_young_card_num(rs_length); 1238 card_num = predict_non_young_card_num(rs_length);
1239 } 1239 }
1240 return predict_base_elapsed_time_ms(pending_cards, card_num); 1240 return predict_base_elapsed_time_ms(pending_cards, card_num);
1241 }
1242
1243 double
1244 G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards,
1245 size_t scanned_cards) {
1246 return
1247 predict_rs_update_time_ms(pending_cards) +
1248 predict_rs_scan_time_ms(scanned_cards) +
1249 predict_constant_other_time_ms();
1250 }
1251
1252 double
1253 G1CollectorPolicy::predict_region_elapsed_time_ms(HeapRegion* hr,
1254 bool young) {
1255 size_t rs_length = hr->rem_set()->occupied();
1256 size_t card_num;
1257 if (gcs_are_young()) {
1258 card_num = predict_young_card_num(rs_length);
1259 } else {
1260 card_num = predict_non_young_card_num(rs_length);
1261 }
1262 size_t bytes_to_copy = predict_bytes_to_copy(hr);
1263
1264 double region_elapsed_time_ms =
1265 predict_rs_scan_time_ms(card_num) +
1266 predict_object_copy_time_ms(bytes_to_copy);
1267
1268 if (young)
1269 region_elapsed_time_ms += predict_young_other_time_ms(1);
1270 else
1271 region_elapsed_time_ms += predict_non_young_other_time_ms(1);
1272
1273 return region_elapsed_time_ms;
1274 } 1241 }
1275 1242
1276 size_t G1CollectorPolicy::predict_bytes_to_copy(HeapRegion* hr) { 1243 size_t G1CollectorPolicy::predict_bytes_to_copy(HeapRegion* hr) {
1277 size_t bytes_to_copy; 1244 size_t bytes_to_copy;
1278 if (hr->is_marked()) 1245 if (hr->is_marked())
1282 int age = hr->age_in_surv_rate_group(); 1249 int age = hr->age_in_surv_rate_group();
1283 double yg_surv_rate = predict_yg_surv_rate(age, hr->surv_rate_group()); 1250 double yg_surv_rate = predict_yg_surv_rate(age, hr->surv_rate_group());
1284 bytes_to_copy = (size_t) ((double) hr->used() * yg_surv_rate); 1251 bytes_to_copy = (size_t) ((double) hr->used() * yg_surv_rate);
1285 } 1252 }
1286 return bytes_to_copy; 1253 return bytes_to_copy;
1254 }
1255
1256 double
1257 G1CollectorPolicy::predict_region_elapsed_time_ms(HeapRegion* hr,
1258 bool for_young_gc) {
1259 size_t rs_length = hr->rem_set()->occupied();
1260 size_t card_num;
1261
1262 // Predicting the number of cards is based on which type of GC
1263 // we're predicting for.
1264 if (for_young_gc) {
1265 card_num = predict_young_card_num(rs_length);
1266 } else {
1267 card_num = predict_non_young_card_num(rs_length);
1268 }
1269 size_t bytes_to_copy = predict_bytes_to_copy(hr);
1270
1271 double region_elapsed_time_ms =
1272 predict_rs_scan_time_ms(card_num) +
1273 predict_object_copy_time_ms(bytes_to_copy);
1274
1275 // The prediction of the "other" time for this region is based
1276 // upon the region type and NOT the GC type.
1277 if (hr->is_young()) {
1278 region_elapsed_time_ms += predict_young_other_time_ms(1);
1279 } else {
1280 region_elapsed_time_ms += predict_non_young_other_time_ms(1);
1281 }
1282 return region_elapsed_time_ms;
1287 } 1283 }
1288 1284
1289 void 1285 void
1290 G1CollectorPolicy::init_cset_region_lengths(uint eden_cset_region_length, 1286 G1CollectorPolicy::init_cset_region_lengths(uint eden_cset_region_length,
1291 uint survivor_cset_region_length) { 1287 uint survivor_cset_region_length) {
1338 1334
1339 return expand_bytes; 1335 return expand_bytes;
1340 } else { 1336 } else {
1341 return 0; 1337 return 0;
1342 } 1338 }
1343 }
1344
1345 class CountCSClosure: public HeapRegionClosure {
1346 G1CollectorPolicy* _g1_policy;
1347 public:
1348 CountCSClosure(G1CollectorPolicy* g1_policy) :
1349 _g1_policy(g1_policy) {}
1350 bool doHeapRegion(HeapRegion* r) {
1351 _g1_policy->_bytes_in_collection_set_before_gc += r->used();
1352 return false;
1353 }
1354 };
1355
1356 void G1CollectorPolicy::count_CS_bytes_used() {
1357 CountCSClosure cs_closure(this);
1358 _g1->collection_set_iterate(&cs_closure);
1359 } 1339 }
1360 1340
1361 void G1CollectorPolicy::print_tracing_info() const { 1341 void G1CollectorPolicy::print_tracing_info() const {
1362 _trace_gen0_time_data.print(); 1342 _trace_gen0_time_data.print();
1363 _trace_gen1_time_data.print(); 1343 _trace_gen1_time_data.print();
1694 // Therefore this routine may be called at a safepoint by the 1674 // Therefore this routine may be called at a safepoint by the
1695 // VM thread, or in-between safepoints by mutator threads (when 1675 // VM thread, or in-between safepoints by mutator threads (when
1696 // retiring the current allocation region) or a concurrent 1676 // retiring the current allocation region) or a concurrent
1697 // refine thread (RSet sampling). 1677 // refine thread (RSet sampling).
1698 1678
1699 double region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, true); 1679 double region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
1700 size_t used_bytes = hr->used(); 1680 size_t used_bytes = hr->used();
1701 _inc_cset_recorded_rs_lengths += rs_length; 1681 _inc_cset_recorded_rs_lengths += rs_length;
1702 _inc_cset_predicted_elapsed_time_ms += region_elapsed_time_ms; 1682 _inc_cset_predicted_elapsed_time_ms += region_elapsed_time_ms;
1703 _inc_cset_bytes_used_before += used_bytes; 1683 _inc_cset_bytes_used_before += used_bytes;
1704 1684
1729 ssize_t old_rs_length = (ssize_t) hr->recorded_rs_length(); 1709 ssize_t old_rs_length = (ssize_t) hr->recorded_rs_length();
1730 ssize_t rs_lengths_diff = (ssize_t) new_rs_length - old_rs_length; 1710 ssize_t rs_lengths_diff = (ssize_t) new_rs_length - old_rs_length;
1731 _inc_cset_recorded_rs_lengths_diffs += rs_lengths_diff; 1711 _inc_cset_recorded_rs_lengths_diffs += rs_lengths_diff;
1732 1712
1733 double old_elapsed_time_ms = hr->predicted_elapsed_time_ms(); 1713 double old_elapsed_time_ms = hr->predicted_elapsed_time_ms();
1734 double new_region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, true); 1714 double new_region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
1735 double elapsed_ms_diff = new_region_elapsed_time_ms - old_elapsed_time_ms; 1715 double elapsed_ms_diff = new_region_elapsed_time_ms - old_elapsed_time_ms;
1736 _inc_cset_predicted_elapsed_time_ms_diffs += elapsed_ms_diff; 1716 _inc_cset_predicted_elapsed_time_ms_diffs += elapsed_ms_diff;
1737 1717
1738 hr->set_recorded_rs_length(new_rs_length); 1718 hr->set_recorded_rs_length(new_rs_length);
1739 hr->set_predicted_elapsed_time_ms(new_region_elapsed_time_ms); 1719 hr->set_predicted_elapsed_time_ms(new_region_elapsed_time_ms);
1852 reclaimable_bytes, perc, threshold); 1832 reclaimable_bytes, perc, threshold);
1853 return true; 1833 return true;
1854 } 1834 }
1855 1835
1856 void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) { 1836 void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
1857 // Set this here - in case we're not doing young collections. 1837 double young_start_time_sec = os::elapsedTime();
1858 double non_young_start_time_sec = os::elapsedTime();
1859 1838
1860 YoungList* young_list = _g1->young_list(); 1839 YoungList* young_list = _g1->young_list();
1861 finalize_incremental_cset_building(); 1840 finalize_incremental_cset_building();
1862 1841
1863 guarantee(target_pause_time_ms > 0.0, 1842 guarantee(target_pause_time_ms > 0.0,
1867 1846
1868 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); 1847 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
1869 double predicted_pause_time_ms = base_time_ms; 1848 double predicted_pause_time_ms = base_time_ms;
1870 double time_remaining_ms = target_pause_time_ms - base_time_ms; 1849 double time_remaining_ms = target_pause_time_ms - base_time_ms;
1871 1850
1872 ergo_verbose3(ErgoCSetConstruction | ErgoHigh, 1851 ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
1873 "start choosing CSet", 1852 "start choosing CSet",
1853 ergo_format_size("_pending_cards")
1874 ergo_format_ms("predicted base time") 1854 ergo_format_ms("predicted base time")
1875 ergo_format_ms("remaining time") 1855 ergo_format_ms("remaining time")
1876 ergo_format_ms("target pause time"), 1856 ergo_format_ms("target pause time"),
1877 base_time_ms, time_remaining_ms, target_pause_time_ms); 1857 _pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
1878 1858
1879 HeapRegion* hr;
1880 double young_start_time_sec = os::elapsedTime();
1881
1882 _collection_set_bytes_used_before = 0;
1883 _last_gc_was_young = gcs_are_young() ? true : false; 1859 _last_gc_was_young = gcs_are_young() ? true : false;
1884 1860
1885 if (_last_gc_was_young) { 1861 if (_last_gc_was_young) {
1886 _trace_gen0_time_data.increment_young_collection_count(); 1862 _trace_gen0_time_data.increment_young_collection_count();
1887 } else { 1863 } else {
1893 // [Newly Young Regions ++ Survivors from last pause]. 1869 // [Newly Young Regions ++ Survivors from last pause].
1894 1870
1895 uint survivor_region_length = young_list->survivor_length(); 1871 uint survivor_region_length = young_list->survivor_length();
1896 uint eden_region_length = young_list->length() - survivor_region_length; 1872 uint eden_region_length = young_list->length() - survivor_region_length;
1897 init_cset_region_lengths(eden_region_length, survivor_region_length); 1873 init_cset_region_lengths(eden_region_length, survivor_region_length);
1898 hr = young_list->first_survivor_region(); 1874
1875 HeapRegion* hr = young_list->first_survivor_region();
1899 while (hr != NULL) { 1876 while (hr != NULL) {
1900 assert(hr->is_survivor(), "badly formed young list"); 1877 assert(hr->is_survivor(), "badly formed young list");
1901 hr->set_young(); 1878 hr->set_young();
1902 hr = hr->get_next_young_region(); 1879 hr = hr->get_next_young_region();
1903 } 1880 }
1924 1901
1925 double young_end_time_sec = os::elapsedTime(); 1902 double young_end_time_sec = os::elapsedTime();
1926 phase_times()->_recorded_young_cset_choice_time_ms = 1903 phase_times()->_recorded_young_cset_choice_time_ms =
1927 (young_end_time_sec - young_start_time_sec) * 1000.0; 1904 (young_end_time_sec - young_start_time_sec) * 1000.0;
1928 1905
1929 // We are doing young collections so reset this. 1906 // Set the start of the non-young choice time.
1930 non_young_start_time_sec = young_end_time_sec; 1907 double non_young_start_time_sec = young_end_time_sec;
1931 1908
1932 if (!gcs_are_young()) { 1909 if (!gcs_are_young()) {
1933 CollectionSetChooser* cset_chooser = _collectionSetChooser; 1910 CollectionSetChooser* cset_chooser = _collectionSetChooser;
1934 cset_chooser->verify(); 1911 cset_chooser->verify();
1935 const uint min_old_cset_length = cset_chooser->calc_min_old_cset_length(); 1912 const uint min_old_cset_length = cset_chooser->calc_min_old_cset_length();
1936 const uint max_old_cset_length = cset_chooser->calc_max_old_cset_length(); 1913 const uint max_old_cset_length = cset_chooser->calc_max_old_cset_length();
1937 1914
1938 uint expensive_region_num = 0; 1915 uint expensive_region_num = 0;
1939 bool check_time_remaining = adaptive_young_list_length(); 1916 bool check_time_remaining = adaptive_young_list_length();
1917
1940 HeapRegion* hr = cset_chooser->peek(); 1918 HeapRegion* hr = cset_chooser->peek();
1941 while (hr != NULL) { 1919 while (hr != NULL) {
1942 if (old_cset_region_length() >= max_old_cset_length) { 1920 if (old_cset_region_length() >= max_old_cset_length) {
1943 // Added maximum number of old regions to the CSet. 1921 // Added maximum number of old regions to the CSet.
1944 ergo_verbose2(ErgoCSetConstruction, 1922 ergo_verbose2(ErgoCSetConstruction,
1948 ergo_format_region("max"), 1926 ergo_format_region("max"),
1949 old_cset_region_length(), max_old_cset_length); 1927 old_cset_region_length(), max_old_cset_length);
1950 break; 1928 break;
1951 } 1929 }
1952 1930
1953 double predicted_time_ms = predict_region_elapsed_time_ms(hr, false); 1931 double predicted_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
1954 if (check_time_remaining) { 1932 if (check_time_remaining) {
1955 if (predicted_time_ms > time_remaining_ms) { 1933 if (predicted_time_ms > time_remaining_ms) {
1956 // Too expensive for the current CSet. 1934 // Too expensive for the current CSet.
1957 1935
1958 if (old_cset_region_length() >= min_old_cset_length) { 1936 if (old_cset_region_length() >= min_old_cset_length) {
2023 cset_chooser->verify(); 2001 cset_chooser->verify();
2024 } 2002 }
2025 2003
2026 stop_incremental_cset_building(); 2004 stop_incremental_cset_building();
2027 2005
2028 count_CS_bytes_used();
2029
2030 ergo_verbose5(ErgoCSetConstruction, 2006 ergo_verbose5(ErgoCSetConstruction,
2031 "finish choosing CSet", 2007 "finish choosing CSet",
2032 ergo_format_region("eden") 2008 ergo_format_region("eden")
2033 ergo_format_region("survivors") 2009 ergo_format_region("survivors")
2034 ergo_format_region("old") 2010 ergo_format_region("old")