1/*
2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2019, Google and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26#include "precompiled.hpp"
27#include "gc/shared/gcOverheadChecker.hpp"
28#include "gc/shared/softRefPolicy.hpp"
29#include "logging/log.hpp"
30
31GCOverheadChecker::GCOverheadChecker() :
32 _gc_overhead_limit_exceeded(false),
33 _print_gc_overhead_limit_would_be_exceeded(false),
34 _gc_overhead_limit_count(0) {
35 assert(GCOverheadLimitThreshold > 0,
36 "No opportunity to clear SoftReferences before GC overhead limit");
37}
38
39void GCOverheadChecker::check_gc_overhead_limit(GCOverheadTester* time_overhead,
40 GCOverheadTester* space_overhead,
41 bool is_full_gc,
42 GCCause::Cause gc_cause,
43 SoftRefPolicy* soft_ref_policy) {
44
45 // Ignore explicit GC's. Exiting here does not set the flag and
46 // does not reset the count.
47 if (GCCause::is_user_requested_gc(gc_cause) ||
48 GCCause::is_serviceability_requested_gc(gc_cause)) {
49 return;
50 }
51
52 bool print_gc_overhead_limit_would_be_exceeded = false;
53 if (is_full_gc) {
54 if (time_overhead->is_exceeded() && space_overhead->is_exceeded()) {
55 // Collections, on average, are taking too much time, and
56 // we have too little space available after a full gc.
57 // At this point the GC overhead limit is being exceeded.
58 _gc_overhead_limit_count++;
59 if (UseGCOverheadLimit) {
60 if (_gc_overhead_limit_count >= GCOverheadLimitThreshold){
61 // All conditions have been met for throwing an out-of-memory
62 set_gc_overhead_limit_exceeded(true);
63 // Avoid consecutive OOM due to the gc time limit by resetting
64 // the counter.
65 reset_gc_overhead_limit_count();
66 } else {
67 // The required consecutive collections which exceed the
68 // GC time limit may or may not have been reached. We
69 // are approaching that condition and so as not to
70 // throw an out-of-memory before all SoftRef's have been
71 // cleared, set _should_clear_all_soft_refs in SoftRefPolicy.
72 // The clearing will be done on the next GC.
73 bool near_limit = gc_overhead_limit_near();
74 if (near_limit) {
75 soft_ref_policy->set_should_clear_all_soft_refs(true);
76 log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
77 }
78 }
79 }
80 // Set this even when the overhead limit will not
81 // cause an out-of-memory. Diagnostic message indicating
82 // that the overhead limit is being exceeded is sometimes
83 // printed.
84 print_gc_overhead_limit_would_be_exceeded = true;
85
86 } else {
87 // Did not exceed overhead limits
88 reset_gc_overhead_limit_count();
89 }
90 }
91
92 if (UseGCOverheadLimit) {
93 if (gc_overhead_limit_exceeded()) {
94 log_trace(gc, ergo)("GC is exceeding overhead limit of " UINTX_FORMAT "%%", GCTimeLimit);
95 reset_gc_overhead_limit_count();
96 } else if (print_gc_overhead_limit_would_be_exceeded) {
97 assert(_gc_overhead_limit_count > 0, "Should not be printing");
98 log_trace(gc, ergo)("GC would exceed overhead limit of " UINTX_FORMAT "%% %d consecutive time(s)",
99 GCTimeLimit, _gc_overhead_limit_count);
100 }
101 }
102}
103