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