src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp

changeset 1822
0bfd3fb24150
parent 435
a61af66fc99e
child 1907
c18cbe5936b8
     1.1 --- a/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp	Fri Apr 09 13:08:34 2010 -0400
     1.2 +++ b/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp	Tue Apr 13 13:52:10 2010 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * Copyright 2004-2010 Sun Microsystems, Inc.  All Rights Reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -44,13 +44,15 @@
    1.11      _survivor_size(init_survivor_size),
    1.12      _gc_pause_goal_sec(gc_pause_goal_sec),
    1.13      _throughput_goal(1.0 - double(1.0 / (1.0 + (double) gc_cost_ratio))),
    1.14 -    _gc_time_limit_exceeded(false),
    1.15 -    _print_gc_time_limit_would_be_exceeded(false),
    1.16 -    _gc_time_limit_count(0),
    1.17 +    _gc_overhead_limit_exceeded(false),
    1.18 +    _print_gc_overhead_limit_would_be_exceeded(false),
    1.19 +    _gc_overhead_limit_count(0),
    1.20      _latest_minor_mutator_interval_seconds(0),
    1.21      _threshold_tolerance_percent(1.0 + ThresholdTolerance/100.0),
    1.22      _young_gen_change_for_minor_throughput(0),
    1.23      _old_gen_change_for_major_throughput(0) {
    1.24 +  assert(AdaptiveSizePolicyGCTimeLimitThreshold > 0,
    1.25 +    "No opportunity to clear SoftReferences before GC overhead limit");
    1.26    _avg_minor_pause    =
    1.27      new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding);
    1.28    _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
    1.29 @@ -278,6 +280,147 @@
    1.30    set_decide_at_full_gc(0);
    1.31  }
    1.32  
    1.33 +void AdaptiveSizePolicy::check_gc_overhead_limit(
    1.34 +                                          size_t young_live,
    1.35 +                                          size_t eden_live,
    1.36 +                                          size_t max_old_gen_size,
    1.37 +                                          size_t max_eden_size,
    1.38 +                                          bool   is_full_gc,
    1.39 +                                          GCCause::Cause gc_cause,
    1.40 +                                          CollectorPolicy* collector_policy) {
    1.41 +
    1.42 +  // Ignore explicit GC's.  Exiting here does not set the flag and
    1.43 +  // does not reset the count.  Updating of the averages for system
    1.44 +  // GC's is still controlled by UseAdaptiveSizePolicyWithSystemGC.
    1.45 +  if (GCCause::is_user_requested_gc(gc_cause) ||
    1.46 +      GCCause::is_serviceability_requested_gc(gc_cause)) {
    1.47 +    return;
    1.48 +  }
    1.49 +  // eden_limit is the upper limit on the size of eden based on
    1.50 +  // the maximum size of the young generation and the sizes
    1.51 +  // of the survivor space.
    1.52 +  // The question being asked is whether the gc costs are high
    1.53 +  // and the space being recovered by a collection is low.
    1.54 +  // free_in_young_gen is the free space in the young generation
    1.55 +  // after a collection and promo_live is the free space in the old
    1.56 +  // generation after a collection.
    1.57 +  //
    1.58 +  // Use the minimum of the current value of the live in the
    1.59 +  // young gen or the average of the live in the young gen.
    1.60 +  // If the current value drops quickly, that should be taken
    1.61 +  // into account (i.e., don't trigger if the amount of free
    1.62 +  // space has suddenly jumped up).  If the current is much
    1.63 +  // higher than the average, use the average since it represents
    1.64 +  // the longer term behavor.
    1.65 +  const size_t live_in_eden =
    1.66 +    MIN2(eden_live, (size_t) avg_eden_live()->average());
    1.67 +  const size_t free_in_eden = max_eden_size > live_in_eden ?
    1.68 +    max_eden_size - live_in_eden : 0;
    1.69 +  const size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
    1.70 +  const size_t total_free_limit = free_in_old_gen + free_in_eden;
    1.71 +  const size_t total_mem = max_old_gen_size + max_eden_size;
    1.72 +  const double mem_free_limit = total_mem * (GCHeapFreeLimit/100.0);
    1.73 +  const double mem_free_old_limit = max_old_gen_size * (GCHeapFreeLimit/100.0);
    1.74 +  const double mem_free_eden_limit = max_eden_size * (GCHeapFreeLimit/100.0);
    1.75 +  const double gc_cost_limit = GCTimeLimit/100.0;
    1.76 +  size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average());
    1.77 +  // But don't force a promo size below the current promo size. Otherwise,
    1.78 +  // the promo size will shrink for no good reason.
    1.79 +  promo_limit = MAX2(promo_limit, _promo_size);
    1.80 +
    1.81 +
    1.82 +  if (PrintAdaptiveSizePolicy && (Verbose ||
    1.83 +      (free_in_old_gen < (size_t) mem_free_old_limit &&
    1.84 +       free_in_eden < (size_t) mem_free_eden_limit))) {
    1.85 +    gclog_or_tty->print_cr(
    1.86 +          "PSAdaptiveSizePolicy::compute_generation_free_space limits:"
    1.87 +          " promo_limit: " SIZE_FORMAT
    1.88 +          " max_eden_size: " SIZE_FORMAT
    1.89 +          " total_free_limit: " SIZE_FORMAT
    1.90 +          " max_old_gen_size: " SIZE_FORMAT
    1.91 +          " max_eden_size: " SIZE_FORMAT
    1.92 +          " mem_free_limit: " SIZE_FORMAT,
    1.93 +          promo_limit, max_eden_size, total_free_limit,
    1.94 +          max_old_gen_size, max_eden_size,
    1.95 +          (size_t) mem_free_limit);
    1.96 +  }
    1.97 +
    1.98 +  bool print_gc_overhead_limit_would_be_exceeded = false;
    1.99 +  if (is_full_gc) {
   1.100 +    if (gc_cost() > gc_cost_limit &&
   1.101 +      free_in_old_gen < (size_t) mem_free_old_limit &&
   1.102 +      free_in_eden < (size_t) mem_free_eden_limit) {
   1.103 +      // Collections, on average, are taking too much time, and
   1.104 +      //      gc_cost() > gc_cost_limit
   1.105 +      // we have too little space available after a full gc.
   1.106 +      //      total_free_limit < mem_free_limit
   1.107 +      // where
   1.108 +      //   total_free_limit is the free space available in
   1.109 +      //     both generations
   1.110 +      //   total_mem is the total space available for allocation
   1.111 +      //     in both generations (survivor spaces are not included
   1.112 +      //     just as they are not included in eden_limit).
   1.113 +      //   mem_free_limit is a fraction of total_mem judged to be an
   1.114 +      //     acceptable amount that is still unused.
   1.115 +      // The heap can ask for the value of this variable when deciding
   1.116 +      // whether to thrown an OutOfMemory error.
   1.117 +      // Note that the gc time limit test only works for the collections
   1.118 +      // of the young gen + tenured gen and not for collections of the
   1.119 +      // permanent gen.  That is because the calculation of the space
   1.120 +      // freed by the collection is the free space in the young gen +
   1.121 +      // tenured gen.
   1.122 +      // At this point the GC overhead limit is being exceeded.
   1.123 +      inc_gc_overhead_limit_count();
   1.124 +      if (UseGCOverheadLimit) {
   1.125 +        if (gc_overhead_limit_count() >=
   1.126 +            AdaptiveSizePolicyGCTimeLimitThreshold){
   1.127 +          // All conditions have been met for throwing an out-of-memory
   1.128 +          set_gc_overhead_limit_exceeded(true);
   1.129 +          // Avoid consecutive OOM due to the gc time limit by resetting
   1.130 +          // the counter.
   1.131 +          reset_gc_overhead_limit_count();
   1.132 +        } else {
   1.133 +          // The required consecutive collections which exceed the
   1.134 +          // GC time limit may or may not have been reached. We
   1.135 +          // are approaching that condition and so as not to
   1.136 +          // throw an out-of-memory before all SoftRef's have been
   1.137 +          // cleared, set _should_clear_all_soft_refs in CollectorPolicy.
   1.138 +          // The clearing will be done on the next GC.
   1.139 +          bool near_limit = gc_overhead_limit_near();
   1.140 +          if (near_limit) {
   1.141 +            collector_policy->set_should_clear_all_soft_refs(true);
   1.142 +            if (PrintGCDetails && Verbose) {
   1.143 +              gclog_or_tty->print_cr("  Nearing GC overhead limit, "
   1.144 +                "will be clearing all SoftReference");
   1.145 +            }
   1.146 +          }
   1.147 +        }
   1.148 +      }
   1.149 +      // Set this even when the overhead limit will not
   1.150 +      // cause an out-of-memory.  Diagnostic message indicating
   1.151 +      // that the overhead limit is being exceeded is sometimes
   1.152 +      // printed.
   1.153 +      print_gc_overhead_limit_would_be_exceeded = true;
   1.154 +
   1.155 +    } else {
   1.156 +      // Did not exceed overhead limits
   1.157 +      reset_gc_overhead_limit_count();
   1.158 +    }
   1.159 +  }
   1.160 +
   1.161 +  if (UseGCOverheadLimit && PrintGCDetails && Verbose) {
   1.162 +    if (gc_overhead_limit_exceeded()) {
   1.163 +      gclog_or_tty->print_cr("      GC is exceeding overhead limit "
   1.164 +        "of %d%%", GCTimeLimit);
   1.165 +      reset_gc_overhead_limit_count();
   1.166 +    } else if (print_gc_overhead_limit_would_be_exceeded) {
   1.167 +      assert(gc_overhead_limit_count() > 0, "Should not be printing");
   1.168 +      gclog_or_tty->print_cr("      GC would exceed overhead limit "
   1.169 +        "of %d%% %d consecutive time(s)",
   1.170 +        GCTimeLimit, gc_overhead_limit_count());
   1.171 +    }
   1.172 +  }
   1.173 +}
   1.174  // Printing
   1.175  
   1.176  bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const {

mercurial