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 }