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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef __clang_major__
26 // FIXME, formats have issues. Disable this macro definition, compile, and study warnings for more information.
27 #define ATTRIBUTE_PRINTF(x,y)
28 #endif
29
30 #include "precompiled.hpp"
31 #include "gc_implementation/g1/concurrentG1Refine.hpp"
32 #include "gc_implementation/g1/concurrentMark.hpp"
33 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
34 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
35 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
36 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
37 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
38 #include "gc_implementation/g1/g1Log.hpp"
39 #include "gc_implementation/g1/heapRegionRemSet.hpp"
40 #include "gc_implementation/shared/gcPolicyCounters.hpp"
41 #include "runtime/arguments.hpp"
42 #include "runtime/java.hpp"
43 #include "runtime/mutexLocker.hpp"
44 #include "utilities/debug.hpp"
45
46 // Different defaults for different number of GC threads
47 // They were chosen by running GCOld and SPECjbb on debris with different
48 // numbers of GC threads and choosing them based on the results
49
285 _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
286
287 // start conservatively (around 50ms is about right)
288 _concurrent_mark_remark_times_ms->add(0.05);
289 _concurrent_mark_cleanup_times_ms->add(0.20);
290 _tenuring_threshold = MaxTenuringThreshold;
291 // _max_survivor_regions will be calculated by
292 // update_young_list_target_length() during initialization.
293 _max_survivor_regions = 0;
294
295 assert(GCTimeRatio > 0,
296 "we should have set it to a default value set_g1_gc_flags() "
297 "if a user set it to 0");
298 _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio));
299
300 uintx reserve_perc = G1ReservePercent;
301 // Put an artificial ceiling on this so that it's not set to a silly value.
302 if (reserve_perc > 50) {
303 reserve_perc = 50;
304 warning("G1ReservePercent is set to a value that is too large, "
305 "it's been updated to %u", reserve_perc);
306 }
307 _reserve_factor = (double) reserve_perc / 100.0;
308 // This will be set when the heap is expanded
309 // for the first time during initialization.
310 _reserve_regions = 0;
311
312 _collectionSetChooser = new CollectionSetChooser();
313 }
314
315 void G1CollectorPolicy::initialize_alignments() {
316 _space_alignment = HeapRegion::GrainBytes;
317 size_t card_table_alignment = GenRemSet::max_alignment_constraint();
318 size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
319 _heap_alignment = MAX3(card_table_alignment, _space_alignment, page_size);
320 }
321
322 void G1CollectorPolicy::initialize_flags() {
323 if (G1HeapRegionSize != HeapRegion::GrainBytes) {
324 FLAG_SET_ERGO(size_t, G1HeapRegionSize, HeapRegion::GrainBytes);
325 }
1783 // Add the region at the left hand side
1784 hr->set_next_in_collection_set(_inc_cset_head);
1785 if (_inc_cset_head == NULL) {
1786 assert(_inc_cset_tail == NULL, "Invariant");
1787 _inc_cset_tail = hr;
1788 }
1789 _inc_cset_head = hr;
1790 }
1791
1792 #ifndef PRODUCT
1793 void G1CollectorPolicy::print_collection_set(HeapRegion* list_head, outputStream* st) {
1794 assert(list_head == inc_cset_head() || list_head == collection_set(), "must be");
1795
1796 st->print_cr("\nCollection_set:");
1797 HeapRegion* csr = list_head;
1798 while (csr != NULL) {
1799 HeapRegion* next = csr->next_in_collection_set();
1800 assert(csr->in_collection_set(), "bad CS");
1801 st->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
1802 HR_FORMAT_PARAMS(csr),
1803 csr->prev_top_at_mark_start(), csr->next_top_at_mark_start(),
1804 csr->age_in_surv_rate_group_cond());
1805 csr = next;
1806 }
1807 }
1808 #endif // !PRODUCT
1809
1810 double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) {
1811 // Returns the given amount of reclaimable bytes (that represents
1812 // the amount of reclaimable space still to be collected) as a
1813 // percentage of the current heap capacity.
1814 size_t capacity_bytes = _g1->capacity();
1815 return (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
1816 }
1817
1818 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
1819 const char* false_action_str) {
1820 CollectionSetChooser* cset_chooser = _collectionSetChooser;
1821 if (cset_chooser->is_empty()) {
1822 ergo_verbose0(ErgoMixedGCs,
1823 false_action_str,
2149 ++_young_pause_num;
2150 }
2151 }
2152
2153 void TraceYoungGenTimeData::increment_mixed_collection_count() {
2154 if(TraceYoungGenTime) {
2155 ++_mixed_pause_num;
2156 }
2157 }
2158
2159 void TraceYoungGenTimeData::print_summary(const char* str,
2160 const NumberSeq* seq) const {
2161 double sum = seq->sum();
2162 gclog_or_tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)",
2163 str, sum / 1000.0, seq->avg());
2164 }
2165
2166 void TraceYoungGenTimeData::print_summary_sd(const char* str,
2167 const NumberSeq* seq) const {
2168 print_summary(str, seq);
2169 gclog_or_tty->print_cr("%+45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
2170 "(num", seq->num(), seq->sd(), seq->maximum());
2171 }
2172
2173 void TraceYoungGenTimeData::print() const {
2174 if (!TraceYoungGenTime) {
2175 return;
2176 }
2177
2178 gclog_or_tty->print_cr("ALL PAUSES");
2179 print_summary_sd(" Total", &_total);
2180 gclog_or_tty->cr();
2181 gclog_or_tty->cr();
2182 gclog_or_tty->print_cr(" Young GC Pauses: %8d", _young_pause_num);
2183 gclog_or_tty->print_cr(" Mixed GC Pauses: %8d", _mixed_pause_num);
2184 gclog_or_tty->cr();
2185
2186 gclog_or_tty->print_cr("EVACUATION PAUSES");
2187
2188 if (_young_pause_num == 0 && _mixed_pause_num == 0) {
2189 gclog_or_tty->print_cr("none");
|
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc_implementation/g1/concurrentG1Refine.hpp"
27 #include "gc_implementation/g1/concurrentMark.hpp"
28 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
30 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
31 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
32 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
33 #include "gc_implementation/g1/g1Log.hpp"
34 #include "gc_implementation/g1/heapRegionRemSet.hpp"
35 #include "gc_implementation/shared/gcPolicyCounters.hpp"
36 #include "runtime/arguments.hpp"
37 #include "runtime/java.hpp"
38 #include "runtime/mutexLocker.hpp"
39 #include "utilities/debug.hpp"
40
41 // Different defaults for different number of GC threads
42 // They were chosen by running GCOld and SPECjbb on debris with different
43 // numbers of GC threads and choosing them based on the results
44
280 _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
281
282 // start conservatively (around 50ms is about right)
283 _concurrent_mark_remark_times_ms->add(0.05);
284 _concurrent_mark_cleanup_times_ms->add(0.20);
285 _tenuring_threshold = MaxTenuringThreshold;
286 // _max_survivor_regions will be calculated by
287 // update_young_list_target_length() during initialization.
288 _max_survivor_regions = 0;
289
290 assert(GCTimeRatio > 0,
291 "we should have set it to a default value set_g1_gc_flags() "
292 "if a user set it to 0");
293 _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio));
294
295 uintx reserve_perc = G1ReservePercent;
296 // Put an artificial ceiling on this so that it's not set to a silly value.
297 if (reserve_perc > 50) {
298 reserve_perc = 50;
299 warning("G1ReservePercent is set to a value that is too large, "
300 "it's been updated to " UINTX_FORMAT, reserve_perc);
301 }
302 _reserve_factor = (double) reserve_perc / 100.0;
303 // This will be set when the heap is expanded
304 // for the first time during initialization.
305 _reserve_regions = 0;
306
307 _collectionSetChooser = new CollectionSetChooser();
308 }
309
310 void G1CollectorPolicy::initialize_alignments() {
311 _space_alignment = HeapRegion::GrainBytes;
312 size_t card_table_alignment = GenRemSet::max_alignment_constraint();
313 size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
314 _heap_alignment = MAX3(card_table_alignment, _space_alignment, page_size);
315 }
316
317 void G1CollectorPolicy::initialize_flags() {
318 if (G1HeapRegionSize != HeapRegion::GrainBytes) {
319 FLAG_SET_ERGO(size_t, G1HeapRegionSize, HeapRegion::GrainBytes);
320 }
1778 // Add the region at the left hand side
1779 hr->set_next_in_collection_set(_inc_cset_head);
1780 if (_inc_cset_head == NULL) {
1781 assert(_inc_cset_tail == NULL, "Invariant");
1782 _inc_cset_tail = hr;
1783 }
1784 _inc_cset_head = hr;
1785 }
1786
1787 #ifndef PRODUCT
1788 void G1CollectorPolicy::print_collection_set(HeapRegion* list_head, outputStream* st) {
1789 assert(list_head == inc_cset_head() || list_head == collection_set(), "must be");
1790
1791 st->print_cr("\nCollection_set:");
1792 HeapRegion* csr = list_head;
1793 while (csr != NULL) {
1794 HeapRegion* next = csr->next_in_collection_set();
1795 assert(csr->in_collection_set(), "bad CS");
1796 st->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
1797 HR_FORMAT_PARAMS(csr),
1798 p2i(csr->prev_top_at_mark_start()), p2i(csr->next_top_at_mark_start()),
1799 csr->age_in_surv_rate_group_cond());
1800 csr = next;
1801 }
1802 }
1803 #endif // !PRODUCT
1804
1805 double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) {
1806 // Returns the given amount of reclaimable bytes (that represents
1807 // the amount of reclaimable space still to be collected) as a
1808 // percentage of the current heap capacity.
1809 size_t capacity_bytes = _g1->capacity();
1810 return (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
1811 }
1812
1813 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
1814 const char* false_action_str) {
1815 CollectionSetChooser* cset_chooser = _collectionSetChooser;
1816 if (cset_chooser->is_empty()) {
1817 ergo_verbose0(ErgoMixedGCs,
1818 false_action_str,
2144 ++_young_pause_num;
2145 }
2146 }
2147
2148 void TraceYoungGenTimeData::increment_mixed_collection_count() {
2149 if(TraceYoungGenTime) {
2150 ++_mixed_pause_num;
2151 }
2152 }
2153
2154 void TraceYoungGenTimeData::print_summary(const char* str,
2155 const NumberSeq* seq) const {
2156 double sum = seq->sum();
2157 gclog_or_tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)",
2158 str, sum / 1000.0, seq->avg());
2159 }
2160
2161 void TraceYoungGenTimeData::print_summary_sd(const char* str,
2162 const NumberSeq* seq) const {
2163 print_summary(str, seq);
2164 gclog_or_tty->print_cr("%45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
2165 "(num", seq->num(), seq->sd(), seq->maximum());
2166 }
2167
2168 void TraceYoungGenTimeData::print() const {
2169 if (!TraceYoungGenTime) {
2170 return;
2171 }
2172
2173 gclog_or_tty->print_cr("ALL PAUSES");
2174 print_summary_sd(" Total", &_total);
2175 gclog_or_tty->cr();
2176 gclog_or_tty->cr();
2177 gclog_or_tty->print_cr(" Young GC Pauses: %8d", _young_pause_num);
2178 gclog_or_tty->print_cr(" Mixed GC Pauses: %8d", _mixed_pause_num);
2179 gclog_or_tty->cr();
2180
2181 gclog_or_tty->print_cr("EVACUATION PAUSES");
2182
2183 if (_young_pause_num == 0 && _mixed_pause_num == 0) {
2184 gclog_or_tty->print_cr("none");
|