1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 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/shared/gcOverheadChecker.hpp" 27 #include "gc/shared/softRefPolicy.hpp" 28 #include "logging/log.hpp" 29 30 GCOverheadChecker::GCOverheadChecker() : 31 _gc_overhead_limit_exceeded(false), 32 _print_gc_overhead_limit_would_be_exceeded(false), 33 _gc_overhead_limit_count(0) { 34 assert(GCOverheadLimitThreshold > 0, 35 "No opportunity to clear SoftReferences before GC overhead limit"); 36 } 37 38 void GCOverheadChecker::check_gc_overhead_limit(GCOverheadTester* time_overhead, 39 GCOverheadTester* space_overhead, 40 bool is_full_gc, 41 GCCause::Cause gc_cause, 42 SoftRefPolicy* soft_ref_policy) { 43 44 // Ignore explicit GC's. Exiting here does not set the flag and 45 // does not reset the count. 46 if (GCCause::is_user_requested_gc(gc_cause) || 47 GCCause::is_serviceability_requested_gc(gc_cause)) { 48 return; 49 } 50 51 bool print_gc_overhead_limit_would_be_exceeded = false; 52 if (is_full_gc) { 53 if (time_overhead->is_exceeded() && space_overhead->is_exceeded()) { 54 // Collections, on average, are taking too much time, and 55 // we have too little space available after a full gc. 56 // At this point the GC overhead limit is being exceeded. 57 _gc_overhead_limit_count++; 58 if (UseGCOverheadLimit) { 59 if (_gc_overhead_limit_count >= GCOverheadLimitThreshold){ 60 // All conditions have been met for throwing an out-of-memory 61 set_gc_overhead_limit_exceeded(true); 62 // Avoid consecutive OOM due to the gc time limit by resetting 63 // the counter. 64 reset_gc_overhead_limit_count(); 65 } else { 66 // The required consecutive collections which exceed the 67 // GC time limit may or may not have been reached. We 68 // are approaching that condition and so as not to 69 // throw an out-of-memory before all SoftRef's have been 70 // cleared, set _should_clear_all_soft_refs in CollectorPolicy. 71 // The clearing will be done on the next GC. 72 bool near_limit = gc_overhead_limit_near(); 73 if (near_limit) { 74 soft_ref_policy->set_should_clear_all_soft_refs(true); 75 log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference"); 76 } 77 } 78 } 79 // Set this even when the overhead limit will not 80 // cause an out-of-memory. Diagnostic message indicating 81 // that the overhead limit is being exceeded is sometimes 82 // printed. 83 print_gc_overhead_limit_would_be_exceeded = true; 84 85 } else { 86 // Did not exceed overhead limits 87 reset_gc_overhead_limit_count(); 88 } 89 } 90 91 if (UseGCOverheadLimit) { 92 if (gc_overhead_limit_exceeded()) { 93 log_trace(gc, ergo)("GC is exceeding overhead limit of " UINTX_FORMAT "%%", GCTimeLimit); 94 reset_gc_overhead_limit_count(); 95 } else if (print_gc_overhead_limit_would_be_exceeded) { 96 assert(_gc_overhead_limit_count > 0, "Should not be printing"); 97 log_trace(gc, ergo)("GC would exceed overhead limit of " UINTX_FORMAT "%% %d consecutive time(s)", 98 GCTimeLimit, _gc_overhead_limit_count); 99 } 100 } 101 }