src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp

Tue, 13 Apr 2010 13:52:10 -0700

author
jmasa
date
Tue, 13 Apr 2010 13:52:10 -0700
changeset 1822
0bfd3fb24150
parent 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
Summary: Ensure a full GC that clears SoftReferences before throwing an out-of-memory
Reviewed-by: ysr, jcoomes

     1 /*
     2  * Copyright 2002-2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_psAdaptiveSizePolicy.cpp.incl"
    28 #include <math.h>
    30 PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
    31                                            size_t init_promo_size,
    32                                            size_t init_survivor_size,
    33                                            size_t intra_generation_alignment,
    34                                            double gc_pause_goal_sec,
    35                                            double gc_minor_pause_goal_sec,
    36                                            uint gc_cost_ratio) :
    37      AdaptiveSizePolicy(init_eden_size,
    38                         init_promo_size,
    39                         init_survivor_size,
    40                         gc_pause_goal_sec,
    41                         gc_cost_ratio),
    42      _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin/
    43        100.0),
    44      _intra_generation_alignment(intra_generation_alignment),
    45      _live_at_last_full_gc(init_promo_size),
    46      _gc_minor_pause_goal_sec(gc_minor_pause_goal_sec),
    47      _latest_major_mutator_interval_seconds(0),
    48      _young_gen_change_for_major_pause_count(0)
    49 {
    50   // Sizing policy statistics
    51   _avg_major_pause    =
    52     new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding);
    53   _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
    54   _avg_major_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
    56   _avg_base_footprint = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
    57   _major_pause_old_estimator =
    58     new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
    59   _major_pause_young_estimator =
    60     new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
    61   _major_collection_estimator =
    62     new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
    64   _young_gen_size_increment_supplement = YoungGenerationSizeSupplement;
    65   _old_gen_size_increment_supplement = TenuredGenerationSizeSupplement;
    67   // Start the timers
    68   _major_timer.start();
    70   _old_gen_policy_is_ready = false;
    71 }
    73 void PSAdaptiveSizePolicy::major_collection_begin() {
    74   // Update the interval time
    75   _major_timer.stop();
    76   // Save most recent collection time
    77   _latest_major_mutator_interval_seconds = _major_timer.seconds();
    78   _major_timer.reset();
    79   _major_timer.start();
    80 }
    82 void PSAdaptiveSizePolicy::update_minor_pause_old_estimator(
    83     double minor_pause_in_ms) {
    84   double promo_size_in_mbytes = ((double)_promo_size)/((double)M);
    85   _minor_pause_old_estimator->update(promo_size_in_mbytes,
    86     minor_pause_in_ms);
    87 }
    89 void PSAdaptiveSizePolicy::major_collection_end(size_t amount_live,
    90   GCCause::Cause gc_cause) {
    91   // Update the pause time.
    92   _major_timer.stop();
    94   if (gc_cause != GCCause::_java_lang_system_gc ||
    95       UseAdaptiveSizePolicyWithSystemGC) {
    96     double major_pause_in_seconds = _major_timer.seconds();
    97     double major_pause_in_ms = major_pause_in_seconds * MILLIUNITS;
    99     // Sample for performance counter
   100     _avg_major_pause->sample(major_pause_in_seconds);
   102     // Cost of collection (unit-less)
   103     double collection_cost = 0.0;
   104     if ((_latest_major_mutator_interval_seconds > 0.0) &&
   105         (major_pause_in_seconds > 0.0)) {
   106       double interval_in_seconds =
   107         _latest_major_mutator_interval_seconds + major_pause_in_seconds;
   108       collection_cost =
   109         major_pause_in_seconds / interval_in_seconds;
   110       avg_major_gc_cost()->sample(collection_cost);
   112       // Sample for performance counter
   113       _avg_major_interval->sample(interval_in_seconds);
   114     }
   116     // Calculate variables used to estimate pause time vs. gen sizes
   117     double eden_size_in_mbytes = ((double)_eden_size)/((double)M);
   118     double promo_size_in_mbytes = ((double)_promo_size)/((double)M);
   119     _major_pause_old_estimator->update(promo_size_in_mbytes,
   120       major_pause_in_ms);
   121     _major_pause_young_estimator->update(eden_size_in_mbytes,
   122       major_pause_in_ms);
   124     if (PrintAdaptiveSizePolicy && Verbose) {
   125       gclog_or_tty->print("psAdaptiveSizePolicy::major_collection_end: "
   126         "major gc cost: %f  average: %f", collection_cost,
   127         avg_major_gc_cost()->average());
   128       gclog_or_tty->print_cr("  major pause: %f major period %f",
   129         major_pause_in_ms,
   130         _latest_major_mutator_interval_seconds * MILLIUNITS);
   131     }
   133     // Calculate variable used to estimate collection cost vs. gen sizes
   134     assert(collection_cost >= 0.0, "Expected to be non-negative");
   135     _major_collection_estimator->update(promo_size_in_mbytes,
   136         collection_cost);
   137   }
   139   // Update the amount live at the end of a full GC
   140   _live_at_last_full_gc = amount_live;
   142   // The policy does not have enough data until at least some major collections
   143   // have been done.
   144   if (_avg_major_pause->count() >= AdaptiveSizePolicyReadyThreshold) {
   145     _old_gen_policy_is_ready = true;
   146   }
   148   // Interval times use this timer to measure the interval that
   149   // the mutator runs.  Reset after the GC pause has been measured.
   150   _major_timer.reset();
   151   _major_timer.start();
   152 }
   154 // If the remaining free space in the old generation is less that
   155 // that expected to be needed by the next collection, do a full
   156 // collection now.
   157 bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) {
   159   // A similar test is done in the scavenge's should_attempt_scavenge().  If
   160   // this is changed, decide if that test should also be changed.
   161   bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes;
   162   if (PrintGCDetails && Verbose) {
   163     if (result) {
   164       gclog_or_tty->print("  full after scavenge: ");
   165     } else {
   166       gclog_or_tty->print("  no full after scavenge: ");
   167     }
   168     gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
   169       " padded_average_promoted " SIZE_FORMAT
   170       " free in old gen " SIZE_FORMAT,
   171       (size_t) average_promoted_in_bytes(),
   172       (size_t) padded_average_promoted_in_bytes(),
   173       old_free_in_bytes);
   174   }
   175   return result;
   176 }
   178 void PSAdaptiveSizePolicy::clear_generation_free_space_flags() {
   180   AdaptiveSizePolicy::clear_generation_free_space_flags();
   182   set_change_old_gen_for_min_pauses(0);
   184   set_change_young_gen_for_maj_pauses(0);
   185 }
   187 // If this is not a full GC, only test and modify the young generation.
   189 void PSAdaptiveSizePolicy::compute_generation_free_space(
   190                                            size_t young_live,
   191                                            size_t eden_live,
   192                                            size_t old_live,
   193                                            size_t perm_live,
   194                                            size_t cur_eden,
   195                                            size_t max_old_gen_size,
   196                                            size_t max_eden_size,
   197                                            bool   is_full_gc,
   198                                            GCCause::Cause gc_cause,
   199                                            CollectorPolicy* collector_policy) {
   201   // Update statistics
   202   // Time statistics are updated as we go, update footprint stats here
   203   _avg_base_footprint->sample(BaseFootPrintEstimate + perm_live);
   204   avg_young_live()->sample(young_live);
   205   avg_eden_live()->sample(eden_live);
   206   if (is_full_gc) {
   207     // old_live is only accurate after a full gc
   208     avg_old_live()->sample(old_live);
   209   }
   211   // This code used to return if the policy was not ready , i.e.,
   212   // policy_is_ready() returning false.  The intent was that
   213   // decisions below needed major collection times and so could
   214   // not be made before two major collections.  A consequence was
   215   // adjustments to the young generation were not done until after
   216   // two major collections even if the minor collections times
   217   // exceeded the requested goals.  Now let the young generation
   218   // adjust for the minor collection times.  Major collection times
   219   // will be zero for the first collection and will naturally be
   220   // ignored.  Tenured generation adjustments are only made at the
   221   // full collections so until the second major collection has
   222   // been reached, no tenured generation adjustments will be made.
   224   // Until we know better, desired promotion size uses the last calculation
   225   size_t desired_promo_size = _promo_size;
   227   // Start eden at the current value.  The desired value that is stored
   228   // in _eden_size is not bounded by constraints of the heap and can
   229   // run away.
   230   //
   231   // As expected setting desired_eden_size to the current
   232   // value of desired_eden_size as a starting point
   233   // caused desired_eden_size to grow way too large and caused
   234   // an overflow down stream.  It may have improved performance in
   235   // some case but is dangerous.
   236   size_t desired_eden_size = cur_eden;
   238 #ifdef ASSERT
   239   size_t original_promo_size = desired_promo_size;
   240   size_t original_eden_size = desired_eden_size;
   241 #endif
   243   // Cache some values. There's a bit of work getting these, so
   244   // we might save a little time.
   245   const double major_cost = major_gc_cost();
   246   const double minor_cost = minor_gc_cost();
   248   // Used for diagnostics
   249   clear_generation_free_space_flags();
   251   // Limits on our growth
   252   size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average());
   254   // This method sets the desired eden size.  That plus the
   255   // desired survivor space sizes sets the desired young generation
   256   // size.  This methods does not know what the desired survivor
   257   // size is but expects that other policy will attempt to make
   258   // the survivor sizes compatible with the live data in the
   259   // young generation.  This limit is an estimate of the space left
   260   // in the young generation after the survivor spaces have been
   261   // subtracted out.
   262   size_t eden_limit = max_eden_size;
   264   // But don't force a promo size below the current promo size. Otherwise,
   265   // the promo size will shrink for no good reason.
   266   promo_limit = MAX2(promo_limit, _promo_size);
   268   const double gc_cost_limit = GCTimeLimit/100.0;
   270   // Which way should we go?
   271   // if pause requirement is not met
   272   //   adjust size of any generation with average paus exceeding
   273   //   the pause limit.  Adjust one pause at a time (the larger)
   274   //   and only make adjustments for the major pause at full collections.
   275   // else if throughput requirement not met
   276   //   adjust the size of the generation with larger gc time.  Only
   277   //   adjust one generation at a time.
   278   // else
   279   //   adjust down the total heap size.  Adjust down the larger of the
   280   //   generations.
   282   // Add some checks for a threshhold for a change.  For example,
   283   // a change less than the necessary alignment is probably not worth
   284   // attempting.
   287   if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) ||
   288       (_avg_major_pause->padded_average() > gc_pause_goal_sec())) {
   289     //
   290     // Check pauses
   291     //
   292     // Make changes only to affect one of the pauses (the larger)
   293     // at a time.
   294     adjust_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
   296   } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
   297     // Adjust only for the minor pause time goal
   298     adjust_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
   300   } else if(adjusted_mutator_cost() < _throughput_goal) {
   301     // This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
   302     // This sometimes resulted in skipping to the minimize footprint
   303     // code.  Change this to try and reduce GC time if mutator time is
   304     // negative for whatever reason.  Or for future consideration,
   305     // bail out of the code if mutator time is negative.
   306     //
   307     // Throughput
   308     //
   309     assert(major_cost >= 0.0, "major cost is < 0.0");
   310     assert(minor_cost >= 0.0, "minor cost is < 0.0");
   311     // Try to reduce the GC times.
   312     adjust_for_throughput(is_full_gc, &desired_promo_size, &desired_eden_size);
   314   } else {
   316     // Be conservative about reducing the footprint.
   317     //   Do a minimum number of major collections first.
   318     //   Have reasonable averages for major and minor collections costs.
   319     if (UseAdaptiveSizePolicyFootprintGoal &&
   320         young_gen_policy_is_ready() &&
   321         avg_major_gc_cost()->average() >= 0.0 &&
   322         avg_minor_gc_cost()->average() >= 0.0) {
   323       size_t desired_sum = desired_eden_size + desired_promo_size;
   324       desired_eden_size = adjust_eden_for_footprint(desired_eden_size,
   325                                                     desired_sum);
   326       if (is_full_gc) {
   327         set_decide_at_full_gc(decide_at_full_gc_true);
   328         desired_promo_size = adjust_promo_for_footprint(desired_promo_size,
   329                                                         desired_sum);
   330       }
   331     }
   332   }
   334   // Note we make the same tests as in the code block below;  the code
   335   // seems a little easier to read with the printing in another block.
   336   if (PrintAdaptiveSizePolicy) {
   337     if (desired_promo_size > promo_limit)  {
   338       // "free_in_old_gen" was the original value for used for promo_limit
   339       size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
   340       gclog_or_tty->print_cr(
   341             "PSAdaptiveSizePolicy::compute_generation_free_space limits:"
   342             " desired_promo_size: " SIZE_FORMAT
   343             " promo_limit: " SIZE_FORMAT
   344             " free_in_old_gen: " SIZE_FORMAT
   345             " max_old_gen_size: " SIZE_FORMAT
   346             " avg_old_live: " SIZE_FORMAT,
   347             desired_promo_size, promo_limit, free_in_old_gen,
   348             max_old_gen_size, (size_t) avg_old_live()->average());
   349     }
   350     if (desired_eden_size > eden_limit) {
   351       gclog_or_tty->print_cr(
   352             "AdaptiveSizePolicy::compute_generation_free_space limits:"
   353             " desired_eden_size: " SIZE_FORMAT
   354             " old_eden_size: " SIZE_FORMAT
   355             " eden_limit: " SIZE_FORMAT
   356             " cur_eden: " SIZE_FORMAT
   357             " max_eden_size: " SIZE_FORMAT
   358             " avg_young_live: " SIZE_FORMAT,
   359             desired_eden_size, _eden_size, eden_limit, cur_eden,
   360             max_eden_size, (size_t)avg_young_live()->average());
   361     }
   362     if (gc_cost() > gc_cost_limit) {
   363       gclog_or_tty->print_cr(
   364             "AdaptiveSizePolicy::compute_generation_free_space: gc time limit"
   365             " gc_cost: %f "
   366             " GCTimeLimit: %d",
   367             gc_cost(), GCTimeLimit);
   368     }
   369   }
   371   // Align everything and make a final limit check
   372   const size_t alignment = _intra_generation_alignment;
   373   desired_eden_size  = align_size_up(desired_eden_size, alignment);
   374   desired_eden_size  = MAX2(desired_eden_size, alignment);
   375   desired_promo_size = align_size_up(desired_promo_size, alignment);
   376   desired_promo_size = MAX2(desired_promo_size, alignment);
   378   eden_limit  = align_size_down(eden_limit, alignment);
   379   promo_limit = align_size_down(promo_limit, alignment);
   381   // Is too much time being spent in GC?
   382   //   Is the heap trying to grow beyond it's limits?
   384   const size_t free_in_old_gen =
   385     (size_t)(max_old_gen_size - avg_old_live()->average());
   386   if (desired_promo_size > free_in_old_gen && desired_eden_size > eden_limit) {
   387     check_gc_overhead_limit(young_live,
   388                             eden_live,
   389                             max_old_gen_size,
   390                             max_eden_size,
   391                             is_full_gc,
   392                             gc_cause,
   393                             collector_policy);
   394   }
   397   // And one last limit check, now that we've aligned things.
   398   if (desired_eden_size > eden_limit) {
   399     // If the policy says to get a larger eden but
   400     // is hitting the limit, don't decrease eden.
   401     // This can lead to a general drifting down of the
   402     // eden size.  Let the tenuring calculation push more
   403     // into the old gen.
   404     desired_eden_size = MAX2(eden_limit, cur_eden);
   405   }
   406   desired_promo_size = MIN2(desired_promo_size, promo_limit);
   409   if (PrintAdaptiveSizePolicy) {
   410     // Timing stats
   411     gclog_or_tty->print(
   412                "PSAdaptiveSizePolicy::compute_generation_free_space: costs"
   413                " minor_time: %f"
   414                " major_cost: %f"
   415                " mutator_cost: %f"
   416                " throughput_goal: %f",
   417                minor_gc_cost(), major_gc_cost(), mutator_cost(),
   418                _throughput_goal);
   420     // We give more details if Verbose is set
   421     if (Verbose) {
   422       gclog_or_tty->print( " minor_pause: %f"
   423                   " major_pause: %f"
   424                   " minor_interval: %f"
   425                   " major_interval: %f"
   426                   " pause_goal: %f",
   427                   _avg_minor_pause->padded_average(),
   428                   _avg_major_pause->padded_average(),
   429                   _avg_minor_interval->average(),
   430                   _avg_major_interval->average(),
   431                   gc_pause_goal_sec());
   432     }
   434     // Footprint stats
   435     gclog_or_tty->print( " live_space: " SIZE_FORMAT
   436                 " free_space: " SIZE_FORMAT,
   437                 live_space(), free_space());
   438     // More detail
   439     if (Verbose) {
   440       gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
   441                   " avg_young_live: " SIZE_FORMAT
   442                   " avg_old_live: " SIZE_FORMAT,
   443                   (size_t)_avg_base_footprint->average(),
   444                   (size_t)avg_young_live()->average(),
   445                   (size_t)avg_old_live()->average());
   446     }
   448     // And finally, our old and new sizes.
   449     gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT
   450                " old_eden_size: " SIZE_FORMAT
   451                " desired_promo_size: " SIZE_FORMAT
   452                " desired_eden_size: " SIZE_FORMAT,
   453                _promo_size, _eden_size,
   454                desired_promo_size, desired_eden_size);
   455     gclog_or_tty->cr();
   456   }
   458   decay_supplemental_growth(is_full_gc);
   460   set_promo_size(desired_promo_size);
   461   set_eden_size(desired_eden_size);
   462 };
   464 void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) {
   465   // Decay the supplemental increment?  Decay the supplement growth
   466   // factor even if it is not used.  It is only meant to give a boost
   467   // to the initial growth and if it is not used, then it was not
   468   // needed.
   469   if (is_full_gc) {
   470     // Don't wait for the threshold value for the major collections.  If
   471     // here, the supplemental growth term was used and should decay.
   472     if ((_avg_major_pause->count() % TenuredGenerationSizeSupplementDecay)
   473         == 0) {
   474       _old_gen_size_increment_supplement =
   475         _old_gen_size_increment_supplement >> 1;
   476     }
   477   } else {
   478     if ((_avg_minor_pause->count() >= AdaptiveSizePolicyReadyThreshold) &&
   479         (_avg_minor_pause->count() % YoungGenerationSizeSupplementDecay) == 0) {
   480       _young_gen_size_increment_supplement =
   481         _young_gen_size_increment_supplement >> 1;
   482     }
   483   }
   484 }
   486 void PSAdaptiveSizePolicy::adjust_for_minor_pause_time(bool is_full_gc,
   487     size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr) {
   489   // Adjust the young generation size to reduce pause time of
   490   // of collections.
   491   //
   492   // The AdaptiveSizePolicyInitializingSteps test is not used
   493   // here.  It has not seemed to be needed but perhaps should
   494   // be added for consistency.
   495   if (minor_pause_young_estimator()->decrement_will_decrease()) {
   496         // reduce eden size
   497     set_change_young_gen_for_min_pauses(
   498           decrease_young_gen_for_min_pauses_true);
   499     *desired_eden_size_ptr = *desired_eden_size_ptr -
   500       eden_decrement_aligned_down(*desired_eden_size_ptr);
   501     } else {
   502       // EXPERIMENTAL ADJUSTMENT
   503       // Only record that the estimator indicated such an action.
   504       // *desired_eden_size_ptr = *desired_eden_size_ptr + eden_heap_delta;
   505       set_change_young_gen_for_min_pauses(
   506           increase_young_gen_for_min_pauses_true);
   507   }
   508   if (PSAdjustTenuredGenForMinorPause) {
   509     // If the desired eden size is as small as it will get,
   510     // try to adjust the old gen size.
   511     if (*desired_eden_size_ptr <= _intra_generation_alignment) {
   512       // Vary the old gen size to reduce the young gen pause.  This
   513       // may not be a good idea.  This is just a test.
   514       if (minor_pause_old_estimator()->decrement_will_decrease()) {
   515         set_change_old_gen_for_min_pauses(
   516           decrease_old_gen_for_min_pauses_true);
   517         *desired_promo_size_ptr =
   518           _promo_size - promo_decrement_aligned_down(*desired_promo_size_ptr);
   519       } else {
   520         set_change_old_gen_for_min_pauses(
   521           increase_old_gen_for_min_pauses_true);
   522         size_t promo_heap_delta =
   523           promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
   524         if ((*desired_promo_size_ptr + promo_heap_delta) >
   525             *desired_promo_size_ptr) {
   526           *desired_promo_size_ptr =
   527             _promo_size + promo_heap_delta;
   528         }
   529       }
   530     }
   531   }
   532 }
   534 void PSAdaptiveSizePolicy::adjust_for_pause_time(bool is_full_gc,
   535                                              size_t* desired_promo_size_ptr,
   536                                              size_t* desired_eden_size_ptr) {
   538   size_t promo_heap_delta = 0;
   539   size_t eden_heap_delta = 0;
   540   // Add some checks for a threshhold for a change.  For example,
   541   // a change less than the required alignment is probably not worth
   542   // attempting.
   543   if (is_full_gc) {
   544     set_decide_at_full_gc(decide_at_full_gc_true);
   545   }
   547   if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
   548     adjust_for_minor_pause_time(is_full_gc,
   549                                 desired_promo_size_ptr,
   550                                 desired_eden_size_ptr);
   551     // major pause adjustments
   552   } else if (is_full_gc) {
   553     // Adjust for the major pause time only at full gc's because the
   554     // affects of a change can only be seen at full gc's.
   556     // Reduce old generation size to reduce pause?
   557     if (major_pause_old_estimator()->decrement_will_decrease()) {
   558       // reduce old generation size
   559       set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true);
   560       promo_heap_delta = promo_decrement_aligned_down(*desired_promo_size_ptr);
   561       *desired_promo_size_ptr = _promo_size - promo_heap_delta;
   562     } else {
   563       // EXPERIMENTAL ADJUSTMENT
   564       // Only record that the estimator indicated such an action.
   565       // *desired_promo_size_ptr = _promo_size +
   566       //   promo_increment_aligned_up(*desired_promo_size_ptr);
   567       set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true);
   568     }
   569     if (PSAdjustYoungGenForMajorPause) {
   570       // If the promo size is at the minimum (i.e., the old gen
   571       // size will not actually decrease), consider changing the
   572       // young gen size.
   573       if (*desired_promo_size_ptr < _intra_generation_alignment) {
   574         // If increasing the young generation will decrease the old gen
   575         // pause, do it.
   576         // During startup there is noise in the statistics for deciding
   577         // on whether to increase or decrease the young gen size.  For
   578         // some number of iterations, just try to increase the young
   579         // gen size if the major pause is too long to try and establish
   580         // good statistics for later decisions.
   581         if (major_pause_young_estimator()->increment_will_decrease() ||
   582           (_young_gen_change_for_major_pause_count
   583             <= AdaptiveSizePolicyInitializingSteps)) {
   584           set_change_young_gen_for_maj_pauses(
   585           increase_young_gen_for_maj_pauses_true);
   586           eden_heap_delta = eden_increment_aligned_up(*desired_eden_size_ptr);
   587           *desired_eden_size_ptr = _eden_size + eden_heap_delta;
   588           _young_gen_change_for_major_pause_count++;
   589         } else {
   590           // Record that decreasing the young gen size would decrease
   591           // the major pause
   592           set_change_young_gen_for_maj_pauses(
   593             decrease_young_gen_for_maj_pauses_true);
   594           eden_heap_delta = eden_decrement_aligned_down(*desired_eden_size_ptr);
   595           *desired_eden_size_ptr = _eden_size - eden_heap_delta;
   596         }
   597       }
   598     }
   599   }
   601   if (PrintAdaptiveSizePolicy && Verbose) {
   602     gclog_or_tty->print_cr(
   603       "AdaptiveSizePolicy::compute_generation_free_space "
   604       "adjusting gen sizes for major pause (avg %f goal %f). "
   605       "desired_promo_size " SIZE_FORMAT "desired_eden_size "
   606        SIZE_FORMAT
   607       " promo delta " SIZE_FORMAT  " eden delta " SIZE_FORMAT,
   608       _avg_major_pause->average(), gc_pause_goal_sec(),
   609       *desired_promo_size_ptr, *desired_eden_size_ptr,
   610       promo_heap_delta, eden_heap_delta);
   611   }
   612 }
   614 void PSAdaptiveSizePolicy::adjust_for_throughput(bool is_full_gc,
   615                                              size_t* desired_promo_size_ptr,
   616                                              size_t* desired_eden_size_ptr) {
   618   // Add some checks for a threshhold for a change.  For example,
   619   // a change less than the required alignment is probably not worth
   620   // attempting.
   621   if (is_full_gc) {
   622     set_decide_at_full_gc(decide_at_full_gc_true);
   623   }
   625   if ((gc_cost() + mutator_cost()) == 0.0) {
   626     return;
   627   }
   629   if (PrintAdaptiveSizePolicy && Verbose) {
   630     gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_for_throughput("
   631       "is_full: %d, promo: " SIZE_FORMAT ",  cur_eden: " SIZE_FORMAT "): ",
   632       is_full_gc, *desired_promo_size_ptr, *desired_eden_size_ptr);
   633     gclog_or_tty->print_cr("mutator_cost %f  major_gc_cost %f "
   634       "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
   635   }
   637   // Tenured generation
   638   if (is_full_gc) {
   640     // Calculate the change to use for the tenured gen.
   641     size_t scaled_promo_heap_delta = 0;
   642     // Can the increment to the generation be scaled?
   643     if (gc_cost() >= 0.0 && major_gc_cost() >= 0.0) {
   644       size_t promo_heap_delta =
   645         promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
   646       double scale_by_ratio = major_gc_cost() / gc_cost();
   647       scaled_promo_heap_delta =
   648         (size_t) (scale_by_ratio * (double) promo_heap_delta);
   649       if (PrintAdaptiveSizePolicy && Verbose) {
   650         gclog_or_tty->print_cr(
   651           "Scaled tenured increment: " SIZE_FORMAT " by %f down to "
   652           SIZE_FORMAT,
   653           promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
   654       }
   655     } else if (major_gc_cost() >= 0.0) {
   656       // Scaling is not going to work.  If the major gc time is the
   657       // larger, give it a full increment.
   658       if (major_gc_cost() >= minor_gc_cost()) {
   659         scaled_promo_heap_delta =
   660           promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
   661       }
   662     } else {
   663       // Don't expect to get here but it's ok if it does
   664       // in the product build since the delta will be 0
   665       // and nothing will change.
   666       assert(false, "Unexpected value for gc costs");
   667     }
   669     switch (AdaptiveSizeThroughPutPolicy) {
   670       case 1:
   671         // Early in the run the statistics might not be good.  Until
   672         // a specific number of collections have been, use the heuristic
   673         // that a larger generation size means lower collection costs.
   674         if (major_collection_estimator()->increment_will_decrease() ||
   675            (_old_gen_change_for_major_throughput
   676             <= AdaptiveSizePolicyInitializingSteps)) {
   677           // Increase tenured generation size to reduce major collection cost
   678           if ((*desired_promo_size_ptr + scaled_promo_heap_delta) >
   679               *desired_promo_size_ptr) {
   680             *desired_promo_size_ptr = _promo_size + scaled_promo_heap_delta;
   681           }
   682           set_change_old_gen_for_throughput(
   683               increase_old_gen_for_throughput_true);
   684               _old_gen_change_for_major_throughput++;
   685         } else {
   686           // EXPERIMENTAL ADJUSTMENT
   687           // Record that decreasing the old gen size would decrease
   688           // the major collection cost but don't do it.
   689           // *desired_promo_size_ptr = _promo_size -
   690           //   promo_decrement_aligned_down(*desired_promo_size_ptr);
   691           set_change_old_gen_for_throughput(
   692                 decrease_old_gen_for_throughput_true);
   693         }
   695         break;
   696       default:
   697         // Simplest strategy
   698         if ((*desired_promo_size_ptr + scaled_promo_heap_delta) >
   699             *desired_promo_size_ptr) {
   700           *desired_promo_size_ptr = *desired_promo_size_ptr +
   701             scaled_promo_heap_delta;
   702         }
   703         set_change_old_gen_for_throughput(
   704           increase_old_gen_for_throughput_true);
   705         _old_gen_change_for_major_throughput++;
   706     }
   708     if (PrintAdaptiveSizePolicy && Verbose) {
   709       gclog_or_tty->print_cr(
   710           "adjusting tenured gen for throughput (avg %f goal %f). "
   711           "desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT ,
   712           mutator_cost(), _throughput_goal,
   713           *desired_promo_size_ptr, scaled_promo_heap_delta);
   714     }
   715   }
   717   // Young generation
   718   size_t scaled_eden_heap_delta = 0;
   719   // Can the increment to the generation be scaled?
   720   if (gc_cost() >= 0.0 && minor_gc_cost() >= 0.0) {
   721     size_t eden_heap_delta =
   722       eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
   723     double scale_by_ratio = minor_gc_cost() / gc_cost();
   724     assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong");
   725     scaled_eden_heap_delta =
   726       (size_t) (scale_by_ratio * (double) eden_heap_delta);
   727     if (PrintAdaptiveSizePolicy && Verbose) {
   728       gclog_or_tty->print_cr(
   729         "Scaled eden increment: " SIZE_FORMAT " by %f down to "
   730         SIZE_FORMAT,
   731         eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
   732     }
   733   } else if (minor_gc_cost() >= 0.0) {
   734     // Scaling is not going to work.  If the minor gc time is the
   735     // larger, give it a full increment.
   736     if (minor_gc_cost() > major_gc_cost()) {
   737       scaled_eden_heap_delta =
   738         eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
   739     }
   740   } else {
   741     // Don't expect to get here but it's ok if it does
   742     // in the product build since the delta will be 0
   743     // and nothing will change.
   744     assert(false, "Unexpected value for gc costs");
   745   }
   747   // Use a heuristic for some number of collections to give
   748   // the averages time to settle down.
   749   switch (AdaptiveSizeThroughPutPolicy) {
   750     case 1:
   751       if (minor_collection_estimator()->increment_will_decrease() ||
   752         (_young_gen_change_for_minor_throughput
   753           <= AdaptiveSizePolicyInitializingSteps)) {
   754         // Expand young generation size to reduce frequency of
   755         // of collections.
   756         if ((*desired_eden_size_ptr + scaled_eden_heap_delta) >
   757             *desired_eden_size_ptr) {
   758           *desired_eden_size_ptr =
   759             *desired_eden_size_ptr + scaled_eden_heap_delta;
   760         }
   761         set_change_young_gen_for_throughput(
   762           increase_young_gen_for_througput_true);
   763         _young_gen_change_for_minor_throughput++;
   764       } else {
   765         // EXPERIMENTAL ADJUSTMENT
   766         // Record that decreasing the young gen size would decrease
   767         // the minor collection cost but don't do it.
   768         // *desired_eden_size_ptr = _eden_size -
   769         //   eden_decrement_aligned_down(*desired_eden_size_ptr);
   770         set_change_young_gen_for_throughput(
   771           decrease_young_gen_for_througput_true);
   772       }
   773           break;
   774     default:
   775       if ((*desired_eden_size_ptr + scaled_eden_heap_delta) >
   776           *desired_eden_size_ptr) {
   777         *desired_eden_size_ptr =
   778           *desired_eden_size_ptr + scaled_eden_heap_delta;
   779       }
   780       set_change_young_gen_for_throughput(
   781         increase_young_gen_for_througput_true);
   782       _young_gen_change_for_minor_throughput++;
   783   }
   785   if (PrintAdaptiveSizePolicy && Verbose) {
   786     gclog_or_tty->print_cr(
   787         "adjusting eden for throughput (avg %f goal %f). desired_eden_size "
   788         SIZE_FORMAT " eden delta " SIZE_FORMAT "\n",
   789       mutator_cost(), _throughput_goal,
   790         *desired_eden_size_ptr, scaled_eden_heap_delta);
   791   }
   792 }
   794 size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
   795     size_t desired_promo_size, size_t desired_sum) {
   796   assert(desired_promo_size <= desired_sum, "Inconsistent parameters");
   797   set_decrease_for_footprint(decrease_old_gen_for_footprint_true);
   799   size_t change = promo_decrement(desired_promo_size);
   800   change = scale_down(change, desired_promo_size, desired_sum);
   802   size_t reduced_size = desired_promo_size - change;
   804   if (PrintAdaptiveSizePolicy && Verbose) {
   805     gclog_or_tty->print_cr(
   806       "AdaptiveSizePolicy::compute_generation_free_space "
   807       "adjusting tenured gen for footprint. "
   808       "starting promo size " SIZE_FORMAT
   809       " reduced promo size " SIZE_FORMAT,
   810       " promo delta " SIZE_FORMAT,
   811       desired_promo_size, reduced_size, change );
   812   }
   814   assert(reduced_size <= desired_promo_size, "Inconsistent result");
   815   return reduced_size;
   816 }
   818 size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint(
   819   size_t desired_eden_size, size_t desired_sum) {
   820   assert(desired_eden_size <= desired_sum, "Inconsistent parameters");
   821   set_decrease_for_footprint(decrease_young_gen_for_footprint_true);
   823   size_t change = eden_decrement(desired_eden_size);
   824   change = scale_down(change, desired_eden_size, desired_sum);
   826   size_t reduced_size = desired_eden_size - change;
   828   if (PrintAdaptiveSizePolicy && Verbose) {
   829     gclog_or_tty->print_cr(
   830       "AdaptiveSizePolicy::compute_generation_free_space "
   831       "adjusting eden for footprint. "
   832       " starting eden size " SIZE_FORMAT
   833       " reduced eden size " SIZE_FORMAT
   834       " eden delta " SIZE_FORMAT,
   835       desired_eden_size, reduced_size, change);
   836   }
   838   assert(reduced_size <= desired_eden_size, "Inconsistent result");
   839   return reduced_size;
   840 }
   842 // Scale down "change" by the factor
   843 //      part / total
   844 // Don't align the results.
   846 size_t PSAdaptiveSizePolicy::scale_down(size_t change,
   847                                         double part,
   848                                         double total) {
   849   assert(part <= total, "Inconsistent input");
   850   size_t reduced_change = change;
   851   if (total > 0) {
   852     double fraction =  part / total;
   853     reduced_change = (size_t) (fraction * (double) change);
   854   }
   855   assert(reduced_change <= change, "Inconsistent result");
   856   return reduced_change;
   857 }
   859 size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden,
   860                                             uint percent_change) {
   861   size_t eden_heap_delta;
   862   eden_heap_delta = cur_eden / 100 * percent_change;
   863   return eden_heap_delta;
   864 }
   866 size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden) {
   867   return eden_increment(cur_eden, YoungGenerationSizeIncrement);
   868 }
   870 size_t PSAdaptiveSizePolicy::eden_increment_aligned_up(size_t cur_eden) {
   871   size_t result = eden_increment(cur_eden, YoungGenerationSizeIncrement);
   872   return align_size_up(result, _intra_generation_alignment);
   873 }
   875 size_t PSAdaptiveSizePolicy::eden_increment_aligned_down(size_t cur_eden) {
   876   size_t result = eden_increment(cur_eden);
   877   return align_size_down(result, _intra_generation_alignment);
   878 }
   880 size_t PSAdaptiveSizePolicy::eden_increment_with_supplement_aligned_up(
   881   size_t cur_eden) {
   882   size_t result = eden_increment(cur_eden,
   883     YoungGenerationSizeIncrement + _young_gen_size_increment_supplement);
   884   return align_size_up(result, _intra_generation_alignment);
   885 }
   887 size_t PSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) {
   888   size_t eden_heap_delta = eden_decrement(cur_eden);
   889   return align_size_down(eden_heap_delta, _intra_generation_alignment);
   890 }
   892 size_t PSAdaptiveSizePolicy::eden_decrement(size_t cur_eden) {
   893   size_t eden_heap_delta = eden_increment(cur_eden) /
   894     AdaptiveSizeDecrementScaleFactor;
   895   return eden_heap_delta;
   896 }
   898 size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo,
   899                                              uint percent_change) {
   900   size_t promo_heap_delta;
   901   promo_heap_delta = cur_promo / 100 * percent_change;
   902   return promo_heap_delta;
   903 }
   905 size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo) {
   906   return promo_increment(cur_promo, TenuredGenerationSizeIncrement);
   907 }
   909 size_t PSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) {
   910   size_t result =  promo_increment(cur_promo, TenuredGenerationSizeIncrement);
   911   return align_size_up(result, _intra_generation_alignment);
   912 }
   914 size_t PSAdaptiveSizePolicy::promo_increment_aligned_down(size_t cur_promo) {
   915   size_t result =  promo_increment(cur_promo, TenuredGenerationSizeIncrement);
   916   return align_size_down(result, _intra_generation_alignment);
   917 }
   919 size_t PSAdaptiveSizePolicy::promo_increment_with_supplement_aligned_up(
   920   size_t cur_promo) {
   921   size_t result =  promo_increment(cur_promo,
   922     TenuredGenerationSizeIncrement + _old_gen_size_increment_supplement);
   923   return align_size_up(result, _intra_generation_alignment);
   924 }
   926 size_t PSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) {
   927   size_t promo_heap_delta = promo_decrement(cur_promo);
   928   return align_size_down(promo_heap_delta, _intra_generation_alignment);
   929 }
   931 size_t PSAdaptiveSizePolicy::promo_decrement(size_t cur_promo) {
   932   size_t promo_heap_delta = promo_increment(cur_promo);
   933   promo_heap_delta = promo_heap_delta / AdaptiveSizeDecrementScaleFactor;
   934   return promo_heap_delta;
   935 }
   937 int PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
   938                                              bool is_survivor_overflow,
   939                                              int tenuring_threshold,
   940                                              size_t survivor_limit) {
   941   assert(survivor_limit >= _intra_generation_alignment,
   942          "survivor_limit too small");
   943   assert((size_t)align_size_down(survivor_limit, _intra_generation_alignment)
   944          == survivor_limit, "survivor_limit not aligned");
   946   // This method is called even if the tenuring threshold and survivor
   947   // spaces are not adjusted so that the averages are sampled above.
   948   if (!UsePSAdaptiveSurvivorSizePolicy ||
   949       !young_gen_policy_is_ready()) {
   950     return tenuring_threshold;
   951   }
   953   // We'll decide whether to increase or decrease the tenuring
   954   // threshold based partly on the newly computed survivor size
   955   // (if we hit the maximum limit allowed, we'll always choose to
   956   // decrement the threshold).
   957   bool incr_tenuring_threshold = false;
   958   bool decr_tenuring_threshold = false;
   960   set_decrement_tenuring_threshold_for_gc_cost(false);
   961   set_increment_tenuring_threshold_for_gc_cost(false);
   962   set_decrement_tenuring_threshold_for_survivor_limit(false);
   964   if (!is_survivor_overflow) {
   965     // Keep running averages on how much survived
   967     // We use the tenuring threshold to equalize the cost of major
   968     // and minor collections.
   969     // ThresholdTolerance is used to indicate how sensitive the
   970     // tenuring threshold is to differences in cost betweent the
   971     // collection types.
   973     // Get the times of interest. This involves a little work, so
   974     // we cache the values here.
   975     const double major_cost = major_gc_cost();
   976     const double minor_cost = minor_gc_cost();
   978     if (minor_cost > major_cost * _threshold_tolerance_percent) {
   979       // Minor times are getting too long;  lower the threshold so
   980       // less survives and more is promoted.
   981       decr_tenuring_threshold = true;
   982       set_decrement_tenuring_threshold_for_gc_cost(true);
   983     } else if (major_cost > minor_cost * _threshold_tolerance_percent) {
   984       // Major times are too long, so we want less promotion.
   985       incr_tenuring_threshold = true;
   986       set_increment_tenuring_threshold_for_gc_cost(true);
   987     }
   989   } else {
   990     // Survivor space overflow occurred, so promoted and survived are
   991     // not accurate. We'll make our best guess by combining survived
   992     // and promoted and count them as survivors.
   993     //
   994     // We'll lower the tenuring threshold to see if we can correct
   995     // things. Also, set the survivor size conservatively. We're
   996     // trying to avoid many overflows from occurring if defnew size
   997     // is just too small.
   999     decr_tenuring_threshold = true;
  1002   // The padded average also maintains a deviation from the average;
  1003   // we use this to see how good of an estimate we have of what survived.
  1004   // We're trying to pad the survivor size as little as possible without
  1005   // overflowing the survivor spaces.
  1006   size_t target_size = align_size_up((size_t)_avg_survived->padded_average(),
  1007                                      _intra_generation_alignment);
  1008   target_size = MAX2(target_size, _intra_generation_alignment);
  1010   if (target_size > survivor_limit) {
  1011     // Target size is bigger than we can handle. Let's also reduce
  1012     // the tenuring threshold.
  1013     target_size = survivor_limit;
  1014     decr_tenuring_threshold = true;
  1015     set_decrement_tenuring_threshold_for_survivor_limit(true);
  1018   // Finally, increment or decrement the tenuring threshold, as decided above.
  1019   // We test for decrementing first, as we might have hit the target size
  1020   // limit.
  1021   if (decr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
  1022     if (tenuring_threshold > 1) {
  1023       tenuring_threshold--;
  1025   } else if (incr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
  1026     if (tenuring_threshold < MaxTenuringThreshold) {
  1027       tenuring_threshold++;
  1031   // We keep a running average of the amount promoted which is used
  1032   // to decide when we should collect the old generation (when
  1033   // the amount of old gen free space is less than what we expect to
  1034   // promote).
  1036   if (PrintAdaptiveSizePolicy) {
  1037     // A little more detail if Verbose is on
  1038     if (Verbose) {
  1039       gclog_or_tty->print( "  avg_survived: %f"
  1040                   "  avg_deviation: %f",
  1041                   _avg_survived->average(),
  1042                   _avg_survived->deviation());
  1045     gclog_or_tty->print( "  avg_survived_padded_avg: %f",
  1046                 _avg_survived->padded_average());
  1048     if (Verbose) {
  1049       gclog_or_tty->print( "  avg_promoted_avg: %f"
  1050                   "  avg_promoted_dev: %f",
  1051                   avg_promoted()->average(),
  1052                   avg_promoted()->deviation());
  1055     gclog_or_tty->print( "  avg_promoted_padded_avg: %f"
  1056                 "  avg_pretenured_padded_avg: %f"
  1057                 "  tenuring_thresh: %d"
  1058                 "  target_size: " SIZE_FORMAT,
  1059                 avg_promoted()->padded_average(),
  1060                 _avg_pretenured->padded_average(),
  1061                 tenuring_threshold, target_size);
  1062     tty->cr();
  1065   set_survivor_size(target_size);
  1067   return tenuring_threshold;
  1070 void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
  1071                                            size_t survived,
  1072                                            size_t promoted) {
  1073   // Update averages
  1074   if (!is_survivor_overflow) {
  1075     // Keep running averages on how much survived
  1076     _avg_survived->sample(survived);
  1077   } else {
  1078     size_t survived_guess = survived + promoted;
  1079     _avg_survived->sample(survived_guess);
  1081   avg_promoted()->sample(promoted + _avg_pretenured->padded_average());
  1083   if (PrintAdaptiveSizePolicy) {
  1084     gclog_or_tty->print(
  1085                   "AdaptiveSizePolicy::compute_survivor_space_size_and_thresh:"
  1086                   "  survived: "  SIZE_FORMAT
  1087                   "  promoted: "  SIZE_FORMAT
  1088                   "  overflow: %s",
  1089                   survived, promoted, is_survivor_overflow ? "true" : "false");
  1093 bool PSAdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st)
  1094   const {
  1096   if (!UseAdaptiveSizePolicy) return false;
  1098   return AdaptiveSizePolicy::print_adaptive_size_policy_on(
  1099                           st,
  1100                           PSScavenge::tenuring_threshold());

mercurial