--- /dev/null 2018-12-04 18:42:22.096405084 +0800 +++ new/src/hotspot/share/gc/shared/gcOverheadChecker.cpp 2018-12-12 17:24:05.353897556 +0800 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc/shared/gcOverheadChecker.hpp" +#include "gc/shared/softRefPolicy.hpp" +#include "logging/log.hpp" + +GCOverheadChecker::GCOverheadChecker() : + _gc_overhead_limit_exceeded(false), + _print_gc_overhead_limit_would_be_exceeded(false), + _gc_overhead_limit_count(0) { + assert(GCOverheadLimitThreshold > 0, + "No opportunity to clear SoftReferences before GC overhead limit"); +} + +void GCOverheadChecker::check_gc_overhead_limit(GCOverheadTester* time_overhead, + GCOverheadTester* space_overhead, + bool is_full_gc, + GCCause::Cause gc_cause, + SoftRefPolicy* soft_ref_policy) { + + // Ignore explicit GC's. Exiting here does not set the flag and + // does not reset the count. + if (GCCause::is_user_requested_gc(gc_cause) || + GCCause::is_serviceability_requested_gc(gc_cause)) { + return; + } + + bool print_gc_overhead_limit_would_be_exceeded = false; + if (is_full_gc) { + if (time_overhead->is_exceeded() && space_overhead->is_exceeded()) { + // Collections, on average, are taking too much time, and + // we have too little space available after a full gc. + // At this point the GC overhead limit is being exceeded. + _gc_overhead_limit_count++; + if (UseGCOverheadLimit) { + if (_gc_overhead_limit_count >= GCOverheadLimitThreshold){ + // All conditions have been met for throwing an out-of-memory + set_gc_overhead_limit_exceeded(true); + // Avoid consecutive OOM due to the gc time limit by resetting + // the counter. + reset_gc_overhead_limit_count(); + } else { + // The required consecutive collections which exceed the + // GC time limit may or may not have been reached. We + // are approaching that condition and so as not to + // throw an out-of-memory before all SoftRef's have been + // cleared, set _should_clear_all_soft_refs in CollectorPolicy. + // The clearing will be done on the next GC. + bool near_limit = gc_overhead_limit_near(); + if (near_limit) { + soft_ref_policy->set_should_clear_all_soft_refs(true); + log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference"); + } + } + } + // Set this even when the overhead limit will not + // cause an out-of-memory. Diagnostic message indicating + // that the overhead limit is being exceeded is sometimes + // printed. + print_gc_overhead_limit_would_be_exceeded = true; + + } else { + // Did not exceed overhead limits + reset_gc_overhead_limit_count(); + } + } + + if (UseGCOverheadLimit) { + if (gc_overhead_limit_exceeded()) { + log_trace(gc, ergo)("GC is exceeding overhead limit of " UINTX_FORMAT "%%", GCTimeLimit); + reset_gc_overhead_limit_count(); + } else if (print_gc_overhead_limit_would_be_exceeded) { + assert(_gc_overhead_limit_count > 0, "Should not be printing"); + log_trace(gc, ergo)("GC would exceed overhead limit of " UINTX_FORMAT "%% %d consecutive time(s)", + GCTimeLimit, _gc_overhead_limit_count); + } + } +}