--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/gcOverheadChecker.cpp Tue Jan 15 15:59:47 2019 -0800
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Google 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);
+ }
+ }
+}