Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @ 8681:27714220e50e
8007036: G1: Too many old regions added to last mixed GC
Summary: Stop adding old regions to collection set when the remaining reclaimable bytes reaches, or goes below, G1HeapWastePercent. Changes were also reviewed by Vitaly Davidovich <vitalyd@gmail.com>.
Reviewed-by: brutisso
author | johnc |
---|---|
date | Mon, 04 Mar 2013 12:42:14 -0800 |
parents | f1fb03a251e9 |
children | cc32ccaaf47f 71013d764f6e |
comparison
equal
deleted
inserted
replaced
8680:0624b9d81255 | 8681:27714220e50e |
---|---|
1804 csr = next; | 1804 csr = next; |
1805 } | 1805 } |
1806 } | 1806 } |
1807 #endif // !PRODUCT | 1807 #endif // !PRODUCT |
1808 | 1808 |
1809 double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) { | |
1810 // Returns the given amount of reclaimable bytes (that represents | |
1811 // the amount of reclaimable space still to be collected) as a | |
1812 // percentage of the current heap capacity. | |
1813 size_t capacity_bytes = _g1->capacity(); | |
1814 return (double) reclaimable_bytes * 100.0 / (double) capacity_bytes; | |
1815 } | |
1816 | |
1809 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str, | 1817 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str, |
1810 const char* false_action_str) { | 1818 const char* false_action_str) { |
1811 CollectionSetChooser* cset_chooser = _collectionSetChooser; | 1819 CollectionSetChooser* cset_chooser = _collectionSetChooser; |
1812 if (cset_chooser->is_empty()) { | 1820 if (cset_chooser->is_empty()) { |
1813 ergo_verbose0(ErgoMixedGCs, | 1821 ergo_verbose0(ErgoMixedGCs, |
1814 false_action_str, | 1822 false_action_str, |
1815 ergo_format_reason("candidate old regions not available")); | 1823 ergo_format_reason("candidate old regions not available")); |
1816 return false; | 1824 return false; |
1817 } | 1825 } |
1826 | |
1827 // Is the amount of uncollected reclaimable space above G1HeapWastePercent? | |
1818 size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes(); | 1828 size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes(); |
1819 size_t capacity_bytes = _g1->capacity(); | 1829 double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes); |
1820 double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes; | |
1821 double threshold = (double) G1HeapWastePercent; | 1830 double threshold = (double) G1HeapWastePercent; |
1822 if (perc < threshold) { | 1831 if (reclaimable_perc <= threshold) { |
1823 ergo_verbose4(ErgoMixedGCs, | 1832 ergo_verbose4(ErgoMixedGCs, |
1824 false_action_str, | 1833 false_action_str, |
1825 ergo_format_reason("reclaimable percentage lower than threshold") | 1834 ergo_format_reason("reclaimable percentage not over threshold") |
1826 ergo_format_region("candidate old regions") | 1835 ergo_format_region("candidate old regions") |
1827 ergo_format_byte_perc("reclaimable") | 1836 ergo_format_byte_perc("reclaimable") |
1828 ergo_format_perc("threshold"), | 1837 ergo_format_perc("threshold"), |
1829 cset_chooser->remaining_regions(), | 1838 cset_chooser->remaining_regions(), |
1830 reclaimable_bytes, perc, threshold); | 1839 reclaimable_bytes, |
1840 reclaimable_perc, threshold); | |
1831 return false; | 1841 return false; |
1832 } | 1842 } |
1833 | 1843 |
1834 ergo_verbose4(ErgoMixedGCs, | 1844 ergo_verbose4(ErgoMixedGCs, |
1835 true_action_str, | 1845 true_action_str, |
1836 ergo_format_reason("candidate old regions available") | 1846 ergo_format_reason("candidate old regions available") |
1837 ergo_format_region("candidate old regions") | 1847 ergo_format_region("candidate old regions") |
1838 ergo_format_byte_perc("reclaimable") | 1848 ergo_format_byte_perc("reclaimable") |
1839 ergo_format_perc("threshold"), | 1849 ergo_format_perc("threshold"), |
1840 cset_chooser->remaining_regions(), | 1850 cset_chooser->remaining_regions(), |
1841 reclaimable_bytes, perc, threshold); | 1851 reclaimable_bytes, |
1852 reclaimable_perc, threshold); | |
1842 return true; | 1853 return true; |
1843 } | 1854 } |
1855 | |
1856 uint G1CollectorPolicy::calc_min_old_cset_length() { | |
1857 // The min old CSet region bound is based on the maximum desired | |
1858 // number of mixed GCs after a cycle. I.e., even if some old regions | |
1859 // look expensive, we should add them to the CSet anyway to make | |
1860 // sure we go through the available old regions in no more than the | |
1861 // maximum desired number of mixed GCs. | |
1862 // | |
1863 // The calculation is based on the number of marked regions we added | |
1864 // to the CSet chooser in the first place, not how many remain, so | |
1865 // that the result is the same during all mixed GCs that follow a cycle. | |
1866 | |
1867 const size_t region_num = (size_t) _collectionSetChooser->length(); | |
1868 const size_t gc_num = (size_t) MAX2(G1MixedGCCountTarget, (uintx) 1); | |
1869 size_t result = region_num / gc_num; | |
1870 // emulate ceiling | |
1871 if (result * gc_num < region_num) { | |
1872 result += 1; | |
1873 } | |
1874 return (uint) result; | |
1875 } | |
1876 | |
1877 uint G1CollectorPolicy::calc_max_old_cset_length() { | |
1878 // The max old CSet region bound is based on the threshold expressed | |
1879 // as a percentage of the heap size. I.e., it should bound the | |
1880 // number of old regions added to the CSet irrespective of how many | |
1881 // of them are available. | |
1882 | |
1883 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
1884 const size_t region_num = g1h->n_regions(); | |
1885 const size_t perc = (size_t) G1OldCSetRegionThresholdPercent; | |
1886 size_t result = region_num * perc / 100; | |
1887 // emulate ceiling | |
1888 if (100 * result < region_num * perc) { | |
1889 result += 1; | |
1890 } | |
1891 return (uint) result; | |
1892 } | |
1893 | |
1844 | 1894 |
1845 void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) { | 1895 void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) { |
1846 double young_start_time_sec = os::elapsedTime(); | 1896 double young_start_time_sec = os::elapsedTime(); |
1847 | 1897 |
1848 YoungList* young_list = _g1->young_list(); | 1898 YoungList* young_list = _g1->young_list(); |
1853 target_pause_time_ms)); | 1903 target_pause_time_ms)); |
1854 guarantee(_collection_set == NULL, "Precondition"); | 1904 guarantee(_collection_set == NULL, "Precondition"); |
1855 | 1905 |
1856 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); | 1906 double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); |
1857 double predicted_pause_time_ms = base_time_ms; | 1907 double predicted_pause_time_ms = base_time_ms; |
1858 double time_remaining_ms = target_pause_time_ms - base_time_ms; | 1908 double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0); |
1859 | 1909 |
1860 ergo_verbose4(ErgoCSetConstruction | ErgoHigh, | 1910 ergo_verbose4(ErgoCSetConstruction | ErgoHigh, |
1861 "start choosing CSet", | 1911 "start choosing CSet", |
1862 ergo_format_size("_pending_cards") | 1912 ergo_format_size("_pending_cards") |
1863 ergo_format_ms("predicted base time") | 1913 ergo_format_ms("predicted base time") |
1891 // Clear the fields that point to the survivor list - they are all young now. | 1941 // Clear the fields that point to the survivor list - they are all young now. |
1892 young_list->clear_survivors(); | 1942 young_list->clear_survivors(); |
1893 | 1943 |
1894 _collection_set = _inc_cset_head; | 1944 _collection_set = _inc_cset_head; |
1895 _collection_set_bytes_used_before = _inc_cset_bytes_used_before; | 1945 _collection_set_bytes_used_before = _inc_cset_bytes_used_before; |
1896 time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms; | 1946 time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0); |
1897 predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; | 1947 predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; |
1898 | 1948 |
1899 ergo_verbose3(ErgoCSetConstruction | ErgoHigh, | 1949 ergo_verbose3(ErgoCSetConstruction | ErgoHigh, |
1900 "add young regions to CSet", | 1950 "add young regions to CSet", |
1901 ergo_format_region("eden") | 1951 ergo_format_region("eden") |
1915 double non_young_start_time_sec = young_end_time_sec; | 1965 double non_young_start_time_sec = young_end_time_sec; |
1916 | 1966 |
1917 if (!gcs_are_young()) { | 1967 if (!gcs_are_young()) { |
1918 CollectionSetChooser* cset_chooser = _collectionSetChooser; | 1968 CollectionSetChooser* cset_chooser = _collectionSetChooser; |
1919 cset_chooser->verify(); | 1969 cset_chooser->verify(); |
1920 const uint min_old_cset_length = cset_chooser->calc_min_old_cset_length(); | 1970 const uint min_old_cset_length = calc_min_old_cset_length(); |
1921 const uint max_old_cset_length = cset_chooser->calc_max_old_cset_length(); | 1971 const uint max_old_cset_length = calc_max_old_cset_length(); |
1922 | 1972 |
1923 uint expensive_region_num = 0; | 1973 uint expensive_region_num = 0; |
1924 bool check_time_remaining = adaptive_young_list_length(); | 1974 bool check_time_remaining = adaptive_young_list_length(); |
1925 | 1975 |
1926 HeapRegion* hr = cset_chooser->peek(); | 1976 HeapRegion* hr = cset_chooser->peek(); |
1931 "finish adding old regions to CSet", | 1981 "finish adding old regions to CSet", |
1932 ergo_format_reason("old CSet region num reached max") | 1982 ergo_format_reason("old CSet region num reached max") |
1933 ergo_format_region("old") | 1983 ergo_format_region("old") |
1934 ergo_format_region("max"), | 1984 ergo_format_region("max"), |
1935 old_cset_region_length(), max_old_cset_length); | 1985 old_cset_region_length(), max_old_cset_length); |
1986 break; | |
1987 } | |
1988 | |
1989 | |
1990 // Stop adding regions if the remaining reclaimable space is | |
1991 // not above G1HeapWastePercent. | |
1992 size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes(); | |
1993 double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes); | |
1994 double threshold = (double) G1HeapWastePercent; | |
1995 if (reclaimable_perc <= threshold) { | |
1996 // We've added enough old regions that the amount of uncollected | |
1997 // reclaimable space is at or below the waste threshold. Stop | |
1998 // adding old regions to the CSet. | |
1999 ergo_verbose5(ErgoCSetConstruction, | |
2000 "finish adding old regions to CSet", | |
2001 ergo_format_reason("reclaimable percentage not over threshold") | |
2002 ergo_format_region("old") | |
2003 ergo_format_region("max") | |
2004 ergo_format_byte_perc("reclaimable") | |
2005 ergo_format_perc("threshold"), | |
2006 old_cset_region_length(), | |
2007 max_old_cset_length, | |
2008 reclaimable_bytes, | |
2009 reclaimable_perc, threshold); | |
1936 break; | 2010 break; |
1937 } | 2011 } |
1938 | 2012 |
1939 double predicted_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young()); | 2013 double predicted_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young()); |
1940 if (check_time_remaining) { | 2014 if (check_time_remaining) { |
1973 break; | 2047 break; |
1974 } | 2048 } |
1975 } | 2049 } |
1976 | 2050 |
1977 // We will add this region to the CSet. | 2051 // We will add this region to the CSet. |
1978 time_remaining_ms -= predicted_time_ms; | 2052 time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0); |
1979 predicted_pause_time_ms += predicted_time_ms; | 2053 predicted_pause_time_ms += predicted_time_ms; |
1980 cset_chooser->remove_and_move_to_next(hr); | 2054 cset_chooser->remove_and_move_to_next(hr); |
1981 _g1->old_set_remove(hr); | 2055 _g1->old_set_remove(hr); |
1982 add_old_region_to_cset(hr); | 2056 add_old_region_to_cset(hr); |
1983 | 2057 |