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

Wed, 15 May 2013 10:41:22 -0700

author
tamao
date
Wed, 15 May 2013 10:41:22 -0700
changeset 5120
eba99d16dc6f
parent 4129
22b8d3d181d9
child 5192
14d3f71f831d
permissions
-rw-r--r--

8007763: Refactoring: split up compute_generation_free_space() into two functions for class PSAdaptiveSizePolicy
Summary: split up compute_generation_free_space() into two functions: compute_eden_space_size() + compute_old_gen_free_space(), each of which (if needed) can be reused without executing an overhead of the other.
Reviewed-by: jmasa, tschatzl
Contributed-by: tamao <tao.mao@oracle.com>

     1 /*
     2  * Copyright (c) 2002, 2013, 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  */
    25 #include "precompiled.hpp"
    26 #include "gc_implementation/parallelScavenge/generationSizer.hpp"
    27 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
    28 #include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
    29 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
    30 #include "gc_implementation/shared/gcPolicyCounters.hpp"
    31 #include "gc_interface/gcCause.hpp"
    32 #include "memory/collectorPolicy.hpp"
    33 #include "runtime/timer.hpp"
    34 #include "utilities/top.hpp"
    36 #include <math.h>
    38 PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
    39                                            size_t init_promo_size,
    40                                            size_t init_survivor_size,
    41                                            size_t intra_generation_alignment,
    42                                            double gc_pause_goal_sec,
    43                                            double gc_minor_pause_goal_sec,
    44                                            uint gc_cost_ratio) :
    45      AdaptiveSizePolicy(init_eden_size,
    46                         init_promo_size,
    47                         init_survivor_size,
    48                         gc_pause_goal_sec,
    49                         gc_cost_ratio),
    50      _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin/
    51        100.0),
    52      _intra_generation_alignment(intra_generation_alignment),
    53      _live_at_last_full_gc(init_promo_size),
    54      _gc_minor_pause_goal_sec(gc_minor_pause_goal_sec),
    55      _latest_major_mutator_interval_seconds(0),
    56      _young_gen_change_for_major_pause_count(0)
    57 {
    58   // Sizing policy statistics
    59   _avg_major_pause    =
    60     new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding);
    61   _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
    62   _avg_major_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
    64   _avg_base_footprint = new AdaptiveWeightedAverage(AdaptiveSizePolicyWeight);
    65   _major_pause_old_estimator =
    66     new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
    67   _major_pause_young_estimator =
    68     new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
    69   _major_collection_estimator =
    70     new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
    72   _young_gen_size_increment_supplement = YoungGenerationSizeSupplement;
    73   _old_gen_size_increment_supplement = TenuredGenerationSizeSupplement;
    75   // Start the timers
    76   _major_timer.start();
    78   _old_gen_policy_is_ready = false;
    79 }
    81 void PSAdaptiveSizePolicy::major_collection_begin() {
    82   // Update the interval time
    83   _major_timer.stop();
    84   // Save most recent collection time
    85   _latest_major_mutator_interval_seconds = _major_timer.seconds();
    86   _major_timer.reset();
    87   _major_timer.start();
    88 }
    90 void PSAdaptiveSizePolicy::update_minor_pause_old_estimator(
    91     double minor_pause_in_ms) {
    92   double promo_size_in_mbytes = ((double)_promo_size)/((double)M);
    93   _minor_pause_old_estimator->update(promo_size_in_mbytes,
    94     minor_pause_in_ms);
    95 }
    97 void PSAdaptiveSizePolicy::major_collection_end(size_t amount_live,
    98   GCCause::Cause gc_cause) {
    99   // Update the pause time.
   100   _major_timer.stop();
   102   if (gc_cause != GCCause::_java_lang_system_gc ||
   103       UseAdaptiveSizePolicyWithSystemGC) {
   104     double major_pause_in_seconds = _major_timer.seconds();
   105     double major_pause_in_ms = major_pause_in_seconds * MILLIUNITS;
   107     // Sample for performance counter
   108     _avg_major_pause->sample(major_pause_in_seconds);
   110     // Cost of collection (unit-less)
   111     double collection_cost = 0.0;
   112     if ((_latest_major_mutator_interval_seconds > 0.0) &&
   113         (major_pause_in_seconds > 0.0)) {
   114       double interval_in_seconds =
   115         _latest_major_mutator_interval_seconds + major_pause_in_seconds;
   116       collection_cost =
   117         major_pause_in_seconds / interval_in_seconds;
   118       avg_major_gc_cost()->sample(collection_cost);
   120       // Sample for performance counter
   121       _avg_major_interval->sample(interval_in_seconds);
   122     }
   124     // Calculate variables used to estimate pause time vs. gen sizes
   125     double eden_size_in_mbytes = ((double)_eden_size)/((double)M);
   126     double promo_size_in_mbytes = ((double)_promo_size)/((double)M);
   127     _major_pause_old_estimator->update(promo_size_in_mbytes,
   128       major_pause_in_ms);
   129     _major_pause_young_estimator->update(eden_size_in_mbytes,
   130       major_pause_in_ms);
   132     if (PrintAdaptiveSizePolicy && Verbose) {
   133       gclog_or_tty->print("psAdaptiveSizePolicy::major_collection_end: "
   134         "major gc cost: %f  average: %f", collection_cost,
   135         avg_major_gc_cost()->average());
   136       gclog_or_tty->print_cr("  major pause: %f major period %f",
   137         major_pause_in_ms,
   138         _latest_major_mutator_interval_seconds * MILLIUNITS);
   139     }
   141     // Calculate variable used to estimate collection cost vs. gen sizes
   142     assert(collection_cost >= 0.0, "Expected to be non-negative");
   143     _major_collection_estimator->update(promo_size_in_mbytes,
   144         collection_cost);
   145   }
   147   // Update the amount live at the end of a full GC
   148   _live_at_last_full_gc = amount_live;
   150   // The policy does not have enough data until at least some major collections
   151   // have been done.
   152   if (_avg_major_pause->count() >= AdaptiveSizePolicyReadyThreshold) {
   153     _old_gen_policy_is_ready = true;
   154   }
   156   // Interval times use this timer to measure the interval that
   157   // the mutator runs.  Reset after the GC pause has been measured.
   158   _major_timer.reset();
   159   _major_timer.start();
   160 }
   162 // If the remaining free space in the old generation is less that
   163 // that expected to be needed by the next collection, do a full
   164 // collection now.
   165 bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) {
   167   // A similar test is done in the scavenge's should_attempt_scavenge().  If
   168   // this is changed, decide if that test should also be changed.
   169   bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes;
   170   if (PrintGCDetails && Verbose) {
   171     if (result) {
   172       gclog_or_tty->print("  full after scavenge: ");
   173     } else {
   174       gclog_or_tty->print("  no full after scavenge: ");
   175     }
   176     gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
   177       " padded_average_promoted " SIZE_FORMAT
   178       " free in old gen " SIZE_FORMAT,
   179       (size_t) average_promoted_in_bytes(),
   180       (size_t) padded_average_promoted_in_bytes(),
   181       old_free_in_bytes);
   182   }
   183   return result;
   184 }
   186 void PSAdaptiveSizePolicy::clear_generation_free_space_flags() {
   188   AdaptiveSizePolicy::clear_generation_free_space_flags();
   190   set_change_old_gen_for_min_pauses(0);
   192   set_change_young_gen_for_maj_pauses(0);
   193 }
   195 // If this is not a full GC, only test and modify the young generation.
   197 void PSAdaptiveSizePolicy::compute_generation_free_space(
   198                                            size_t young_live,
   199                                            size_t eden_live,
   200                                            size_t old_live,
   201                                            size_t cur_eden,
   202                                            size_t max_old_gen_size,
   203                                            size_t max_eden_size,
   204                                            bool   is_full_gc) {
   205   compute_eden_space_size(young_live,
   206                           eden_live,
   207                           cur_eden,
   208                           max_eden_size,
   209                           is_full_gc);
   211   compute_old_gen_free_space(old_live,
   212                              cur_eden,
   213                              max_old_gen_size,
   214                              is_full_gc);
   215 }
   217 void PSAdaptiveSizePolicy::compute_eden_space_size(
   218                                            size_t young_live,
   219                                            size_t eden_live,
   220                                            size_t cur_eden,
   221                                            size_t max_eden_size,
   222                                            bool   is_full_gc) {
   224   // Update statistics
   225   // Time statistics are updated as we go, update footprint stats here
   226   _avg_base_footprint->sample(BaseFootPrintEstimate);
   227   avg_young_live()->sample(young_live);
   228   avg_eden_live()->sample(eden_live);
   230   // This code used to return if the policy was not ready , i.e.,
   231   // policy_is_ready() returning false.  The intent was that
   232   // decisions below needed major collection times and so could
   233   // not be made before two major collections.  A consequence was
   234   // adjustments to the young generation were not done until after
   235   // two major collections even if the minor collections times
   236   // exceeded the requested goals.  Now let the young generation
   237   // adjust for the minor collection times.  Major collection times
   238   // will be zero for the first collection and will naturally be
   239   // ignored.  Tenured generation adjustments are only made at the
   240   // full collections so until the second major collection has
   241   // been reached, no tenured generation adjustments will be made.
   243   // Until we know better, desired promotion size uses the last calculation
   244   size_t desired_promo_size = _promo_size;
   246   // Start eden at the current value.  The desired value that is stored
   247   // in _eden_size is not bounded by constraints of the heap and can
   248   // run away.
   249   //
   250   // As expected setting desired_eden_size to the current
   251   // value of desired_eden_size as a starting point
   252   // caused desired_eden_size to grow way too large and caused
   253   // an overflow down stream.  It may have improved performance in
   254   // some case but is dangerous.
   255   size_t desired_eden_size = cur_eden;
   257   // Cache some values. There's a bit of work getting these, so
   258   // we might save a little time.
   259   const double major_cost = major_gc_cost();
   260   const double minor_cost = minor_gc_cost();
   262   // This method sets the desired eden size.  That plus the
   263   // desired survivor space sizes sets the desired young generation
   264   // size.  This methods does not know what the desired survivor
   265   // size is but expects that other policy will attempt to make
   266   // the survivor sizes compatible with the live data in the
   267   // young generation.  This limit is an estimate of the space left
   268   // in the young generation after the survivor spaces have been
   269   // subtracted out.
   270   size_t eden_limit = max_eden_size;
   272   const double gc_cost_limit = GCTimeLimit/100.0;
   274   // Which way should we go?
   275   // if pause requirement is not met
   276   //   adjust size of any generation with average paus exceeding
   277   //   the pause limit.  Adjust one pause at a time (the larger)
   278   //   and only make adjustments for the major pause at full collections.
   279   // else if throughput requirement not met
   280   //   adjust the size of the generation with larger gc time.  Only
   281   //   adjust one generation at a time.
   282   // else
   283   //   adjust down the total heap size.  Adjust down the larger of the
   284   //   generations.
   286   // Add some checks for a threshold for a change.  For example,
   287   // a change less than the necessary alignment is probably not worth
   288   // attempting.
   291   if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) ||
   292       (_avg_major_pause->padded_average() > gc_pause_goal_sec())) {
   293     //
   294     // Check pauses
   295     //
   296     // Make changes only to affect one of the pauses (the larger)
   297     // at a time.
   298     adjust_eden_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
   300   } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
   301     // Adjust only for the minor pause time goal
   302     adjust_eden_for_minor_pause_time(is_full_gc, &desired_eden_size);
   304   } else if(adjusted_mutator_cost() < _throughput_goal) {
   305     // This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
   306     // This sometimes resulted in skipping to the minimize footprint
   307     // code.  Change this to try and reduce GC time if mutator time is
   308     // negative for whatever reason.  Or for future consideration,
   309     // bail out of the code if mutator time is negative.
   310     //
   311     // Throughput
   312     //
   313     assert(major_cost >= 0.0, "major cost is < 0.0");
   314     assert(minor_cost >= 0.0, "minor cost is < 0.0");
   315     // Try to reduce the GC times.
   316     adjust_eden_for_throughput(is_full_gc, &desired_eden_size);
   318   } else {
   320     // Be conservative about reducing the footprint.
   321     //   Do a minimum number of major collections first.
   322     //   Have reasonable averages for major and minor collections costs.
   323     if (UseAdaptiveSizePolicyFootprintGoal &&
   324         young_gen_policy_is_ready() &&
   325         avg_major_gc_cost()->average() >= 0.0 &&
   326         avg_minor_gc_cost()->average() >= 0.0) {
   327       size_t desired_sum = desired_eden_size + desired_promo_size;
   328       desired_eden_size = adjust_eden_for_footprint(desired_eden_size, desired_sum);
   329     }
   330   }
   332   // Note we make the same tests as in the code block below;  the code
   333   // seems a little easier to read with the printing in another block.
   334   if (PrintAdaptiveSizePolicy) {
   335     if (desired_eden_size > eden_limit) {
   336       gclog_or_tty->print_cr(
   337             "PSAdaptiveSizePolicy::compute_eden_space_size limits:"
   338             " desired_eden_size: " SIZE_FORMAT
   339             " old_eden_size: " SIZE_FORMAT
   340             " eden_limit: " SIZE_FORMAT
   341             " cur_eden: " SIZE_FORMAT
   342             " max_eden_size: " SIZE_FORMAT
   343             " avg_young_live: " SIZE_FORMAT,
   344             desired_eden_size, _eden_size, eden_limit, cur_eden,
   345             max_eden_size, (size_t)avg_young_live()->average());
   346     }
   347     if (gc_cost() > gc_cost_limit) {
   348       gclog_or_tty->print_cr(
   349             "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit"
   350             " gc_cost: %f "
   351             " GCTimeLimit: %d",
   352             gc_cost(), GCTimeLimit);
   353     }
   354   }
   356   // Align everything and make a final limit check
   357   const size_t alignment = _intra_generation_alignment;
   358   desired_eden_size  = align_size_up(desired_eden_size, alignment);
   359   desired_eden_size  = MAX2(desired_eden_size, alignment);
   361   eden_limit  = align_size_down(eden_limit, alignment);
   363   // And one last limit check, now that we've aligned things.
   364   if (desired_eden_size > eden_limit) {
   365     // If the policy says to get a larger eden but
   366     // is hitting the limit, don't decrease eden.
   367     // This can lead to a general drifting down of the
   368     // eden size.  Let the tenuring calculation push more
   369     // into the old gen.
   370     desired_eden_size = MAX2(eden_limit, cur_eden);
   371   }
   373   if (PrintAdaptiveSizePolicy) {
   374     // Timing stats
   375     gclog_or_tty->print(
   376                "PSAdaptiveSizePolicy::compute_eden_space_size: costs"
   377                " minor_time: %f"
   378                " major_cost: %f"
   379                " mutator_cost: %f"
   380                " throughput_goal: %f",
   381                minor_gc_cost(), major_gc_cost(), mutator_cost(),
   382                _throughput_goal);
   384     // We give more details if Verbose is set
   385     if (Verbose) {
   386       gclog_or_tty->print( " minor_pause: %f"
   387                   " major_pause: %f"
   388                   " minor_interval: %f"
   389                   " major_interval: %f"
   390                   " pause_goal: %f",
   391                   _avg_minor_pause->padded_average(),
   392                   _avg_major_pause->padded_average(),
   393                   _avg_minor_interval->average(),
   394                   _avg_major_interval->average(),
   395                   gc_pause_goal_sec());
   396     }
   398     // Footprint stats
   399     gclog_or_tty->print( " live_space: " SIZE_FORMAT
   400                 " free_space: " SIZE_FORMAT,
   401                 live_space(), free_space());
   402     // More detail
   403     if (Verbose) {
   404       gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
   405                   " avg_young_live: " SIZE_FORMAT
   406                   " avg_old_live: " SIZE_FORMAT,
   407                   (size_t)_avg_base_footprint->average(),
   408                   (size_t)avg_young_live()->average(),
   409                   (size_t)avg_old_live()->average());
   410     }
   412     // And finally, our old and new sizes.
   413     gclog_or_tty->print(" old_eden_size: " SIZE_FORMAT
   414                " desired_eden_size: " SIZE_FORMAT,
   415                _eden_size, desired_eden_size);
   416     gclog_or_tty->cr();
   417   }
   419   set_eden_size(desired_eden_size);
   420 }
   422 void PSAdaptiveSizePolicy::compute_old_gen_free_space(
   423                                            size_t old_live,
   424                                            size_t cur_eden,
   425                                            size_t max_old_gen_size,
   426                                            bool   is_full_gc) {
   428   // Update statistics
   429   // Time statistics are updated as we go, update footprint stats here
   430   if (is_full_gc) {
   431     // old_live is only accurate after a full gc
   432     avg_old_live()->sample(old_live);
   433   }
   435   // This code used to return if the policy was not ready , i.e.,
   436   // policy_is_ready() returning false.  The intent was that
   437   // decisions below needed major collection times and so could
   438   // not be made before two major collections.  A consequence was
   439   // adjustments to the young generation were not done until after
   440   // two major collections even if the minor collections times
   441   // exceeded the requested goals.  Now let the young generation
   442   // adjust for the minor collection times.  Major collection times
   443   // will be zero for the first collection and will naturally be
   444   // ignored.  Tenured generation adjustments are only made at the
   445   // full collections so until the second major collection has
   446   // been reached, no tenured generation adjustments will be made.
   448   // Until we know better, desired promotion size uses the last calculation
   449   size_t desired_promo_size = _promo_size;
   451   // Start eden at the current value.  The desired value that is stored
   452   // in _eden_size is not bounded by constraints of the heap and can
   453   // run away.
   454   //
   455   // As expected setting desired_eden_size to the current
   456   // value of desired_eden_size as a starting point
   457   // caused desired_eden_size to grow way too large and caused
   458   // an overflow down stream.  It may have improved performance in
   459   // some case but is dangerous.
   460   size_t desired_eden_size = cur_eden;
   462   // Cache some values. There's a bit of work getting these, so
   463   // we might save a little time.
   464   const double major_cost = major_gc_cost();
   465   const double minor_cost = minor_gc_cost();
   467   // Limits on our growth
   468   size_t promo_limit = (size_t)(max_old_gen_size - avg_old_live()->average());
   470   // But don't force a promo size below the current promo size. Otherwise,
   471   // the promo size will shrink for no good reason.
   472   promo_limit = MAX2(promo_limit, _promo_size);
   474   const double gc_cost_limit = GCTimeLimit/100.0;
   476   // Which way should we go?
   477   // if pause requirement is not met
   478   //   adjust size of any generation with average paus exceeding
   479   //   the pause limit.  Adjust one pause at a time (the larger)
   480   //   and only make adjustments for the major pause at full collections.
   481   // else if throughput requirement not met
   482   //   adjust the size of the generation with larger gc time.  Only
   483   //   adjust one generation at a time.
   484   // else
   485   //   adjust down the total heap size.  Adjust down the larger of the
   486   //   generations.
   488   // Add some checks for a threshhold for a change.  For example,
   489   // a change less than the necessary alignment is probably not worth
   490   // attempting.
   492   if ((_avg_minor_pause->padded_average() > gc_pause_goal_sec()) ||
   493       (_avg_major_pause->padded_average() > gc_pause_goal_sec())) {
   494     //
   495     // Check pauses
   496     //
   497     // Make changes only to affect one of the pauses (the larger)
   498     // at a time.
   499     if (is_full_gc) {
   500       set_decide_at_full_gc(decide_at_full_gc_true);
   501       adjust_promo_for_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
   502     }
   503   } else if (_avg_minor_pause->padded_average() > gc_minor_pause_goal_sec()) {
   504     // Adjust only for the minor pause time goal
   505     adjust_promo_for_minor_pause_time(is_full_gc, &desired_promo_size, &desired_eden_size);
   506   } else if(adjusted_mutator_cost() < _throughput_goal) {
   507     // This branch used to require that (mutator_cost() > 0.0 in 1.4.2.
   508     // This sometimes resulted in skipping to the minimize footprint
   509     // code.  Change this to try and reduce GC time if mutator time is
   510     // negative for whatever reason.  Or for future consideration,
   511     // bail out of the code if mutator time is negative.
   512     //
   513     // Throughput
   514     //
   515     assert(major_cost >= 0.0, "major cost is < 0.0");
   516     assert(minor_cost >= 0.0, "minor cost is < 0.0");
   517     // Try to reduce the GC times.
   518     if (is_full_gc) {
   519       set_decide_at_full_gc(decide_at_full_gc_true);
   520       adjust_promo_for_throughput(is_full_gc, &desired_promo_size);
   521     }
   522   } else {
   524     // Be conservative about reducing the footprint.
   525     //   Do a minimum number of major collections first.
   526     //   Have reasonable averages for major and minor collections costs.
   527     if (UseAdaptiveSizePolicyFootprintGoal &&
   528         young_gen_policy_is_ready() &&
   529         avg_major_gc_cost()->average() >= 0.0 &&
   530         avg_minor_gc_cost()->average() >= 0.0) {
   531       if (is_full_gc) {
   532         set_decide_at_full_gc(decide_at_full_gc_true);
   533         size_t desired_sum = desired_eden_size + desired_promo_size;
   534         desired_promo_size = adjust_promo_for_footprint(desired_promo_size, desired_sum);
   535       }
   536     }
   537   }
   539   // Note we make the same tests as in the code block below;  the code
   540   // seems a little easier to read with the printing in another block.
   541   if (PrintAdaptiveSizePolicy) {
   542     if (desired_promo_size > promo_limit)  {
   543       // "free_in_old_gen" was the original value for used for promo_limit
   544       size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
   545       gclog_or_tty->print_cr(
   546             "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:"
   547             " desired_promo_size: " SIZE_FORMAT
   548             " promo_limit: " SIZE_FORMAT
   549             " free_in_old_gen: " SIZE_FORMAT
   550             " max_old_gen_size: " SIZE_FORMAT
   551             " avg_old_live: " SIZE_FORMAT,
   552             desired_promo_size, promo_limit, free_in_old_gen,
   553             max_old_gen_size, (size_t) avg_old_live()->average());
   554     }
   555     if (gc_cost() > gc_cost_limit) {
   556       gclog_or_tty->print_cr(
   557             "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit"
   558             " gc_cost: %f "
   559             " GCTimeLimit: %d",
   560             gc_cost(), GCTimeLimit);
   561     }
   562   }
   564   // Align everything and make a final limit check
   565   const size_t alignment = _intra_generation_alignment;
   566   desired_promo_size = align_size_up(desired_promo_size, alignment);
   567   desired_promo_size = MAX2(desired_promo_size, alignment);
   569   promo_limit = align_size_down(promo_limit, alignment);
   571   // And one last limit check, now that we've aligned things.
   572   desired_promo_size = MIN2(desired_promo_size, promo_limit);
   574   if (PrintAdaptiveSizePolicy) {
   575     // Timing stats
   576     gclog_or_tty->print(
   577                "PSAdaptiveSizePolicy::compute_old_gen_free_space: costs"
   578                " minor_time: %f"
   579                " major_cost: %f"
   580                " mutator_cost: %f"
   581                " throughput_goal: %f",
   582                minor_gc_cost(), major_gc_cost(), mutator_cost(),
   583                _throughput_goal);
   585     // We give more details if Verbose is set
   586     if (Verbose) {
   587       gclog_or_tty->print( " minor_pause: %f"
   588                   " major_pause: %f"
   589                   " minor_interval: %f"
   590                   " major_interval: %f"
   591                   " pause_goal: %f",
   592                   _avg_minor_pause->padded_average(),
   593                   _avg_major_pause->padded_average(),
   594                   _avg_minor_interval->average(),
   595                   _avg_major_interval->average(),
   596                   gc_pause_goal_sec());
   597     }
   599     // Footprint stats
   600     gclog_or_tty->print( " live_space: " SIZE_FORMAT
   601                 " free_space: " SIZE_FORMAT,
   602                 live_space(), free_space());
   603     // More detail
   604     if (Verbose) {
   605       gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
   606                   " avg_young_live: " SIZE_FORMAT
   607                   " avg_old_live: " SIZE_FORMAT,
   608                   (size_t)_avg_base_footprint->average(),
   609                   (size_t)avg_young_live()->average(),
   610                   (size_t)avg_old_live()->average());
   611     }
   613     // And finally, our old and new sizes.
   614     gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT
   615                " desired_promo_size: " SIZE_FORMAT,
   616                _promo_size, desired_promo_size);
   617     gclog_or_tty->cr();
   618   }
   620   set_promo_size(desired_promo_size);
   621 }
   623 void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) {
   624   // Decay the supplemental increment?  Decay the supplement growth
   625   // factor even if it is not used.  It is only meant to give a boost
   626   // to the initial growth and if it is not used, then it was not
   627   // needed.
   628   if (is_full_gc) {
   629     // Don't wait for the threshold value for the major collections.  If
   630     // here, the supplemental growth term was used and should decay.
   631     if ((_avg_major_pause->count() % TenuredGenerationSizeSupplementDecay)
   632         == 0) {
   633       _old_gen_size_increment_supplement =
   634         _old_gen_size_increment_supplement >> 1;
   635     }
   636   } else {
   637     if ((_avg_minor_pause->count() >= AdaptiveSizePolicyReadyThreshold) &&
   638         (_avg_minor_pause->count() % YoungGenerationSizeSupplementDecay) == 0) {
   639       _young_gen_size_increment_supplement =
   640         _young_gen_size_increment_supplement >> 1;
   641     }
   642   }
   643 }
   645 void PSAdaptiveSizePolicy::adjust_promo_for_minor_pause_time(bool is_full_gc,
   646     size_t* desired_promo_size_ptr, size_t* desired_eden_size_ptr) {
   648   if (PSAdjustTenuredGenForMinorPause) {
   649     if (is_full_gc) {
   650       set_decide_at_full_gc(decide_at_full_gc_true);
   651     }
   652     // If the desired eden size is as small as it will get,
   653     // try to adjust the old gen size.
   654     if (*desired_eden_size_ptr <= _intra_generation_alignment) {
   655       // Vary the old gen size to reduce the young gen pause.  This
   656       // may not be a good idea.  This is just a test.
   657       if (minor_pause_old_estimator()->decrement_will_decrease()) {
   658         set_change_old_gen_for_min_pauses(decrease_old_gen_for_min_pauses_true);
   659         *desired_promo_size_ptr =
   660           _promo_size - promo_decrement_aligned_down(*desired_promo_size_ptr);
   661       } else {
   662         set_change_old_gen_for_min_pauses(increase_old_gen_for_min_pauses_true);
   663         size_t promo_heap_delta =
   664           promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
   665         if ((*desired_promo_size_ptr + promo_heap_delta) >
   666             *desired_promo_size_ptr) {
   667           *desired_promo_size_ptr =
   668             _promo_size + promo_heap_delta;
   669         }
   670       }
   671     }
   672   }
   673 }
   675 void PSAdaptiveSizePolicy::adjust_eden_for_minor_pause_time(bool is_full_gc,
   676     size_t* desired_eden_size_ptr) {
   678   // Adjust the young generation size to reduce pause time of
   679   // of collections.
   680   //
   681   // The AdaptiveSizePolicyInitializingSteps test is not used
   682   // here.  It has not seemed to be needed but perhaps should
   683   // be added for consistency.
   684   if (minor_pause_young_estimator()->decrement_will_decrease()) {
   685         // reduce eden size
   686     set_change_young_gen_for_min_pauses(
   687           decrease_young_gen_for_min_pauses_true);
   688     *desired_eden_size_ptr = *desired_eden_size_ptr -
   689       eden_decrement_aligned_down(*desired_eden_size_ptr);
   690     } else {
   691       // EXPERIMENTAL ADJUSTMENT
   692       // Only record that the estimator indicated such an action.
   693       // *desired_eden_size_ptr = *desired_eden_size_ptr + eden_heap_delta;
   694       set_change_young_gen_for_min_pauses(
   695           increase_young_gen_for_min_pauses_true);
   696   }
   697 }
   699 void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(bool is_full_gc,
   700                                              size_t* desired_promo_size_ptr,
   701                                              size_t* desired_eden_size_ptr) {
   703   size_t promo_heap_delta = 0;
   704   // Add some checks for a threshold for a change.  For example,
   705   // a change less than the required alignment is probably not worth
   706   // attempting.
   708   if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
   709     adjust_promo_for_minor_pause_time(is_full_gc, desired_promo_size_ptr, desired_eden_size_ptr);
   710     // major pause adjustments
   711   } else if (is_full_gc) {
   712     // Adjust for the major pause time only at full gc's because the
   713     // affects of a change can only be seen at full gc's.
   715     // Reduce old generation size to reduce pause?
   716     if (major_pause_old_estimator()->decrement_will_decrease()) {
   717       // reduce old generation size
   718       set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true);
   719       promo_heap_delta = promo_decrement_aligned_down(*desired_promo_size_ptr);
   720       *desired_promo_size_ptr = _promo_size - promo_heap_delta;
   721     } else {
   722       // EXPERIMENTAL ADJUSTMENT
   723       // Only record that the estimator indicated such an action.
   724       // *desired_promo_size_ptr = _promo_size +
   725       //   promo_increment_aligned_up(*desired_promo_size_ptr);
   726       set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true);
   727     }
   728   }
   730   if (PrintAdaptiveSizePolicy && Verbose) {
   731     gclog_or_tty->print_cr(
   732       "PSAdaptiveSizePolicy::compute_old_gen_free_space "
   733       "adjusting gen sizes for major pause (avg %f goal %f). "
   734       "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
   735       _avg_major_pause->average(), gc_pause_goal_sec(),
   736       *desired_promo_size_ptr, promo_heap_delta);
   737   }
   738 }
   740 void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
   741                                              size_t* desired_promo_size_ptr,
   742                                              size_t* desired_eden_size_ptr) {
   744   size_t eden_heap_delta = 0;
   745   // Add some checks for a threshold for a change.  For example,
   746   // a change less than the required alignment is probably not worth
   747   // attempting.
   748   if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
   749     adjust_eden_for_minor_pause_time(is_full_gc,
   750                                 desired_eden_size_ptr);
   751     // major pause adjustments
   752   } else if (is_full_gc) {
   753     // Adjust for the major pause time only at full gc's because the
   754     // affects of a change can only be seen at full gc's.
   755     if (PSAdjustYoungGenForMajorPause) {
   756       // If the promo size is at the minimum (i.e., the old gen
   757       // size will not actually decrease), consider changing the
   758       // young gen size.
   759       if (*desired_promo_size_ptr < _intra_generation_alignment) {
   760         // If increasing the young generation will decrease the old gen
   761         // pause, do it.
   762         // During startup there is noise in the statistics for deciding
   763         // on whether to increase or decrease the young gen size.  For
   764         // some number of iterations, just try to increase the young
   765         // gen size if the major pause is too long to try and establish
   766         // good statistics for later decisions.
   767         if (major_pause_young_estimator()->increment_will_decrease() ||
   768           (_young_gen_change_for_major_pause_count
   769             <= AdaptiveSizePolicyInitializingSteps)) {
   770           set_change_young_gen_for_maj_pauses(
   771           increase_young_gen_for_maj_pauses_true);
   772           eden_heap_delta = eden_increment_aligned_up(*desired_eden_size_ptr);
   773           *desired_eden_size_ptr = _eden_size + eden_heap_delta;
   774           _young_gen_change_for_major_pause_count++;
   775         } else {
   776           // Record that decreasing the young gen size would decrease
   777           // the major pause
   778           set_change_young_gen_for_maj_pauses(
   779             decrease_young_gen_for_maj_pauses_true);
   780           eden_heap_delta = eden_decrement_aligned_down(*desired_eden_size_ptr);
   781           *desired_eden_size_ptr = _eden_size - eden_heap_delta;
   782         }
   783       }
   784     }
   785   }
   787   if (PrintAdaptiveSizePolicy && Verbose) {
   788     gclog_or_tty->print_cr(
   789       "PSAdaptiveSizePolicy::compute_eden_space_size "
   790       "adjusting gen sizes for major pause (avg %f goal %f). "
   791       "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
   792       _avg_major_pause->average(), gc_pause_goal_sec(),
   793       *desired_eden_size_ptr, eden_heap_delta);
   794   }
   795 }
   797 void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
   798                                              size_t* desired_promo_size_ptr) {
   800   // Add some checks for a threshold for a change.  For example,
   801   // a change less than the required alignment is probably not worth
   802   // attempting.
   804   if ((gc_cost() + mutator_cost()) == 0.0) {
   805     return;
   806   }
   808   if (PrintAdaptiveSizePolicy && Verbose) {
   809     gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_promo_for_throughput("
   810       "is_full: %d, promo: " SIZE_FORMAT "): ",
   811       is_full_gc, *desired_promo_size_ptr);
   812     gclog_or_tty->print_cr("mutator_cost %f  major_gc_cost %f "
   813       "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
   814   }
   816   // Tenured generation
   817   if (is_full_gc) {
   818     // Calculate the change to use for the tenured gen.
   819     size_t scaled_promo_heap_delta = 0;
   820     // Can the increment to the generation be scaled?
   821     if (gc_cost() >= 0.0 && major_gc_cost() >= 0.0) {
   822       size_t promo_heap_delta =
   823         promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
   824       double scale_by_ratio = major_gc_cost() / gc_cost();
   825       scaled_promo_heap_delta =
   826         (size_t) (scale_by_ratio * (double) promo_heap_delta);
   827       if (PrintAdaptiveSizePolicy && Verbose) {
   828         gclog_or_tty->print_cr(
   829           "Scaled tenured increment: " SIZE_FORMAT " by %f down to "
   830           SIZE_FORMAT,
   831           promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
   832       }
   833     } else if (major_gc_cost() >= 0.0) {
   834       // Scaling is not going to work.  If the major gc time is the
   835       // larger, give it a full increment.
   836       if (major_gc_cost() >= minor_gc_cost()) {
   837         scaled_promo_heap_delta =
   838           promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
   839       }
   840     } else {
   841       // Don't expect to get here but it's ok if it does
   842       // in the product build since the delta will be 0
   843       // and nothing will change.
   844       assert(false, "Unexpected value for gc costs");
   845     }
   847     switch (AdaptiveSizeThroughPutPolicy) {
   848       case 1:
   849         // Early in the run the statistics might not be good.  Until
   850         // a specific number of collections have been, use the heuristic
   851         // that a larger generation size means lower collection costs.
   852         if (major_collection_estimator()->increment_will_decrease() ||
   853            (_old_gen_change_for_major_throughput
   854             <= AdaptiveSizePolicyInitializingSteps)) {
   855           // Increase tenured generation size to reduce major collection cost
   856           if ((*desired_promo_size_ptr + scaled_promo_heap_delta) >
   857               *desired_promo_size_ptr) {
   858             *desired_promo_size_ptr = _promo_size + scaled_promo_heap_delta;
   859           }
   860           set_change_old_gen_for_throughput(
   861               increase_old_gen_for_throughput_true);
   862               _old_gen_change_for_major_throughput++;
   863         } else {
   864           // EXPERIMENTAL ADJUSTMENT
   865           // Record that decreasing the old gen size would decrease
   866           // the major collection cost but don't do it.
   867           // *desired_promo_size_ptr = _promo_size -
   868           //   promo_decrement_aligned_down(*desired_promo_size_ptr);
   869           set_change_old_gen_for_throughput(
   870                 decrease_old_gen_for_throughput_true);
   871         }
   873         break;
   874       default:
   875         // Simplest strategy
   876         if ((*desired_promo_size_ptr + scaled_promo_heap_delta) >
   877             *desired_promo_size_ptr) {
   878           *desired_promo_size_ptr = *desired_promo_size_ptr +
   879             scaled_promo_heap_delta;
   880         }
   881         set_change_old_gen_for_throughput(
   882           increase_old_gen_for_throughput_true);
   883         _old_gen_change_for_major_throughput++;
   884     }
   886     if (PrintAdaptiveSizePolicy && Verbose) {
   887       gclog_or_tty->print_cr(
   888           "adjusting tenured gen for throughput (avg %f goal %f). "
   889           "desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT ,
   890           mutator_cost(), _throughput_goal,
   891           *desired_promo_size_ptr, scaled_promo_heap_delta);
   892     }
   893   }
   894 }
   896 void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc,
   897                                              size_t* desired_eden_size_ptr) {
   899   // Add some checks for a threshold for a change.  For example,
   900   // a change less than the required alignment is probably not worth
   901   // attempting.
   903   if ((gc_cost() + mutator_cost()) == 0.0) {
   904     return;
   905   }
   907   if (PrintAdaptiveSizePolicy && Verbose) {
   908     gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_eden_for_throughput("
   909       "is_full: %d, cur_eden: " SIZE_FORMAT "): ",
   910       is_full_gc, *desired_eden_size_ptr);
   911     gclog_or_tty->print_cr("mutator_cost %f  major_gc_cost %f "
   912       "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
   913   }
   915   // Young generation
   916   size_t scaled_eden_heap_delta = 0;
   917   // Can the increment to the generation be scaled?
   918   if (gc_cost() >= 0.0 && minor_gc_cost() >= 0.0) {
   919     size_t eden_heap_delta =
   920       eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
   921     double scale_by_ratio = minor_gc_cost() / gc_cost();
   922     assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong");
   923     scaled_eden_heap_delta =
   924       (size_t) (scale_by_ratio * (double) eden_heap_delta);
   925     if (PrintAdaptiveSizePolicy && Verbose) {
   926       gclog_or_tty->print_cr(
   927         "Scaled eden increment: " SIZE_FORMAT " by %f down to "
   928         SIZE_FORMAT,
   929         eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
   930     }
   931   } else if (minor_gc_cost() >= 0.0) {
   932     // Scaling is not going to work.  If the minor gc time is the
   933     // larger, give it a full increment.
   934     if (minor_gc_cost() > major_gc_cost()) {
   935       scaled_eden_heap_delta =
   936         eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
   937     }
   938   } else {
   939     // Don't expect to get here but it's ok if it does
   940     // in the product build since the delta will be 0
   941     // and nothing will change.
   942     assert(false, "Unexpected value for gc costs");
   943   }
   945   // Use a heuristic for some number of collections to give
   946   // the averages time to settle down.
   947   switch (AdaptiveSizeThroughPutPolicy) {
   948     case 1:
   949       if (minor_collection_estimator()->increment_will_decrease() ||
   950         (_young_gen_change_for_minor_throughput
   951           <= AdaptiveSizePolicyInitializingSteps)) {
   952         // Expand young generation size to reduce frequency of
   953         // of collections.
   954         if ((*desired_eden_size_ptr + scaled_eden_heap_delta) >
   955             *desired_eden_size_ptr) {
   956           *desired_eden_size_ptr =
   957             *desired_eden_size_ptr + scaled_eden_heap_delta;
   958         }
   959         set_change_young_gen_for_throughput(
   960           increase_young_gen_for_througput_true);
   961         _young_gen_change_for_minor_throughput++;
   962       } else {
   963         // EXPERIMENTAL ADJUSTMENT
   964         // Record that decreasing the young gen size would decrease
   965         // the minor collection cost but don't do it.
   966         // *desired_eden_size_ptr = _eden_size -
   967         //   eden_decrement_aligned_down(*desired_eden_size_ptr);
   968         set_change_young_gen_for_throughput(
   969           decrease_young_gen_for_througput_true);
   970       }
   971           break;
   972     default:
   973       if ((*desired_eden_size_ptr + scaled_eden_heap_delta) >
   974           *desired_eden_size_ptr) {
   975         *desired_eden_size_ptr =
   976           *desired_eden_size_ptr + scaled_eden_heap_delta;
   977       }
   978       set_change_young_gen_for_throughput(
   979         increase_young_gen_for_througput_true);
   980       _young_gen_change_for_minor_throughput++;
   981   }
   983   if (PrintAdaptiveSizePolicy && Verbose) {
   984     gclog_or_tty->print_cr(
   985         "adjusting eden for throughput (avg %f goal %f). desired_eden_size "
   986         SIZE_FORMAT " eden delta " SIZE_FORMAT "\n",
   987       mutator_cost(), _throughput_goal,
   988         *desired_eden_size_ptr, scaled_eden_heap_delta);
   989   }
   990 }
   992 size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
   993     size_t desired_promo_size, size_t desired_sum) {
   994   assert(desired_promo_size <= desired_sum, "Inconsistent parameters");
   995   set_decrease_for_footprint(decrease_old_gen_for_footprint_true);
   997   size_t change = promo_decrement(desired_promo_size);
   998   change = scale_down(change, desired_promo_size, desired_sum);
  1000   size_t reduced_size = desired_promo_size - change;
  1002   if (PrintAdaptiveSizePolicy && Verbose) {
  1003     gclog_or_tty->print_cr(
  1004       "AdaptiveSizePolicy::compute_generation_free_space "
  1005       "adjusting tenured gen for footprint. "
  1006       "starting promo size " SIZE_FORMAT
  1007       " reduced promo size " SIZE_FORMAT,
  1008       " promo delta " SIZE_FORMAT,
  1009       desired_promo_size, reduced_size, change );
  1012   assert(reduced_size <= desired_promo_size, "Inconsistent result");
  1013   return reduced_size;
  1016 size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint(
  1017   size_t desired_eden_size, size_t desired_sum) {
  1018   assert(desired_eden_size <= desired_sum, "Inconsistent parameters");
  1019   set_decrease_for_footprint(decrease_young_gen_for_footprint_true);
  1021   size_t change = eden_decrement(desired_eden_size);
  1022   change = scale_down(change, desired_eden_size, desired_sum);
  1024   size_t reduced_size = desired_eden_size - change;
  1026   if (PrintAdaptiveSizePolicy && Verbose) {
  1027     gclog_or_tty->print_cr(
  1028       "AdaptiveSizePolicy::compute_generation_free_space "
  1029       "adjusting eden for footprint. "
  1030       " starting eden size " SIZE_FORMAT
  1031       " reduced eden size " SIZE_FORMAT
  1032       " eden delta " SIZE_FORMAT,
  1033       desired_eden_size, reduced_size, change);
  1036   assert(reduced_size <= desired_eden_size, "Inconsistent result");
  1037   return reduced_size;
  1040 // Scale down "change" by the factor
  1041 //      part / total
  1042 // Don't align the results.
  1044 size_t PSAdaptiveSizePolicy::scale_down(size_t change,
  1045                                         double part,
  1046                                         double total) {
  1047   assert(part <= total, "Inconsistent input");
  1048   size_t reduced_change = change;
  1049   if (total > 0) {
  1050     double fraction =  part / total;
  1051     reduced_change = (size_t) (fraction * (double) change);
  1053   assert(reduced_change <= change, "Inconsistent result");
  1054   return reduced_change;
  1057 size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden,
  1058                                             uint percent_change) {
  1059   size_t eden_heap_delta;
  1060   eden_heap_delta = cur_eden / 100 * percent_change;
  1061   return eden_heap_delta;
  1064 size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden) {
  1065   return eden_increment(cur_eden, YoungGenerationSizeIncrement);
  1068 size_t PSAdaptiveSizePolicy::eden_increment_aligned_up(size_t cur_eden) {
  1069   size_t result = eden_increment(cur_eden, YoungGenerationSizeIncrement);
  1070   return align_size_up(result, _intra_generation_alignment);
  1073 size_t PSAdaptiveSizePolicy::eden_increment_aligned_down(size_t cur_eden) {
  1074   size_t result = eden_increment(cur_eden);
  1075   return align_size_down(result, _intra_generation_alignment);
  1078 size_t PSAdaptiveSizePolicy::eden_increment_with_supplement_aligned_up(
  1079   size_t cur_eden) {
  1080   size_t result = eden_increment(cur_eden,
  1081     YoungGenerationSizeIncrement + _young_gen_size_increment_supplement);
  1082   return align_size_up(result, _intra_generation_alignment);
  1085 size_t PSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) {
  1086   size_t eden_heap_delta = eden_decrement(cur_eden);
  1087   return align_size_down(eden_heap_delta, _intra_generation_alignment);
  1090 size_t PSAdaptiveSizePolicy::eden_decrement(size_t cur_eden) {
  1091   size_t eden_heap_delta = eden_increment(cur_eden) /
  1092     AdaptiveSizeDecrementScaleFactor;
  1093   return eden_heap_delta;
  1096 size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo,
  1097                                              uint percent_change) {
  1098   size_t promo_heap_delta;
  1099   promo_heap_delta = cur_promo / 100 * percent_change;
  1100   return promo_heap_delta;
  1103 size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo) {
  1104   return promo_increment(cur_promo, TenuredGenerationSizeIncrement);
  1107 size_t PSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) {
  1108   size_t result =  promo_increment(cur_promo, TenuredGenerationSizeIncrement);
  1109   return align_size_up(result, _intra_generation_alignment);
  1112 size_t PSAdaptiveSizePolicy::promo_increment_aligned_down(size_t cur_promo) {
  1113   size_t result =  promo_increment(cur_promo, TenuredGenerationSizeIncrement);
  1114   return align_size_down(result, _intra_generation_alignment);
  1117 size_t PSAdaptiveSizePolicy::promo_increment_with_supplement_aligned_up(
  1118   size_t cur_promo) {
  1119   size_t result =  promo_increment(cur_promo,
  1120     TenuredGenerationSizeIncrement + _old_gen_size_increment_supplement);
  1121   return align_size_up(result, _intra_generation_alignment);
  1124 size_t PSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) {
  1125   size_t promo_heap_delta = promo_decrement(cur_promo);
  1126   return align_size_down(promo_heap_delta, _intra_generation_alignment);
  1129 size_t PSAdaptiveSizePolicy::promo_decrement(size_t cur_promo) {
  1130   size_t promo_heap_delta = promo_increment(cur_promo);
  1131   promo_heap_delta = promo_heap_delta / AdaptiveSizeDecrementScaleFactor;
  1132   return promo_heap_delta;
  1135 uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
  1136                                              bool is_survivor_overflow,
  1137                                              uint tenuring_threshold,
  1138                                              size_t survivor_limit) {
  1139   assert(survivor_limit >= _intra_generation_alignment,
  1140          "survivor_limit too small");
  1141   assert((size_t)align_size_down(survivor_limit, _intra_generation_alignment)
  1142          == survivor_limit, "survivor_limit not aligned");
  1144   // This method is called even if the tenuring threshold and survivor
  1145   // spaces are not adjusted so that the averages are sampled above.
  1146   if (!UsePSAdaptiveSurvivorSizePolicy ||
  1147       !young_gen_policy_is_ready()) {
  1148     return tenuring_threshold;
  1151   // We'll decide whether to increase or decrease the tenuring
  1152   // threshold based partly on the newly computed survivor size
  1153   // (if we hit the maximum limit allowed, we'll always choose to
  1154   // decrement the threshold).
  1155   bool incr_tenuring_threshold = false;
  1156   bool decr_tenuring_threshold = false;
  1158   set_decrement_tenuring_threshold_for_gc_cost(false);
  1159   set_increment_tenuring_threshold_for_gc_cost(false);
  1160   set_decrement_tenuring_threshold_for_survivor_limit(false);
  1162   if (!is_survivor_overflow) {
  1163     // Keep running averages on how much survived
  1165     // We use the tenuring threshold to equalize the cost of major
  1166     // and minor collections.
  1167     // ThresholdTolerance is used to indicate how sensitive the
  1168     // tenuring threshold is to differences in cost betweent the
  1169     // collection types.
  1171     // Get the times of interest. This involves a little work, so
  1172     // we cache the values here.
  1173     const double major_cost = major_gc_cost();
  1174     const double minor_cost = minor_gc_cost();
  1176     if (minor_cost > major_cost * _threshold_tolerance_percent) {
  1177       // Minor times are getting too long;  lower the threshold so
  1178       // less survives and more is promoted.
  1179       decr_tenuring_threshold = true;
  1180       set_decrement_tenuring_threshold_for_gc_cost(true);
  1181     } else if (major_cost > minor_cost * _threshold_tolerance_percent) {
  1182       // Major times are too long, so we want less promotion.
  1183       incr_tenuring_threshold = true;
  1184       set_increment_tenuring_threshold_for_gc_cost(true);
  1187   } else {
  1188     // Survivor space overflow occurred, so promoted and survived are
  1189     // not accurate. We'll make our best guess by combining survived
  1190     // and promoted and count them as survivors.
  1191     //
  1192     // We'll lower the tenuring threshold to see if we can correct
  1193     // things. Also, set the survivor size conservatively. We're
  1194     // trying to avoid many overflows from occurring if defnew size
  1195     // is just too small.
  1197     decr_tenuring_threshold = true;
  1200   // The padded average also maintains a deviation from the average;
  1201   // we use this to see how good of an estimate we have of what survived.
  1202   // We're trying to pad the survivor size as little as possible without
  1203   // overflowing the survivor spaces.
  1204   size_t target_size = align_size_up((size_t)_avg_survived->padded_average(),
  1205                                      _intra_generation_alignment);
  1206   target_size = MAX2(target_size, _intra_generation_alignment);
  1208   if (target_size > survivor_limit) {
  1209     // Target size is bigger than we can handle. Let's also reduce
  1210     // the tenuring threshold.
  1211     target_size = survivor_limit;
  1212     decr_tenuring_threshold = true;
  1213     set_decrement_tenuring_threshold_for_survivor_limit(true);
  1216   // Finally, increment or decrement the tenuring threshold, as decided above.
  1217   // We test for decrementing first, as we might have hit the target size
  1218   // limit.
  1219   if (decr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
  1220     if (tenuring_threshold > 1) {
  1221       tenuring_threshold--;
  1223   } else if (incr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
  1224     if (tenuring_threshold < MaxTenuringThreshold) {
  1225       tenuring_threshold++;
  1229   // We keep a running average of the amount promoted which is used
  1230   // to decide when we should collect the old generation (when
  1231   // the amount of old gen free space is less than what we expect to
  1232   // promote).
  1234   if (PrintAdaptiveSizePolicy) {
  1235     // A little more detail if Verbose is on
  1236     if (Verbose) {
  1237       gclog_or_tty->print( "  avg_survived: %f"
  1238                   "  avg_deviation: %f",
  1239                   _avg_survived->average(),
  1240                   _avg_survived->deviation());
  1243     gclog_or_tty->print( "  avg_survived_padded_avg: %f",
  1244                 _avg_survived->padded_average());
  1246     if (Verbose) {
  1247       gclog_or_tty->print( "  avg_promoted_avg: %f"
  1248                   "  avg_promoted_dev: %f",
  1249                   avg_promoted()->average(),
  1250                   avg_promoted()->deviation());
  1253     gclog_or_tty->print( "  avg_promoted_padded_avg: %f"
  1254                 "  avg_pretenured_padded_avg: %f"
  1255                 "  tenuring_thresh: %d"
  1256                 "  target_size: " SIZE_FORMAT,
  1257                 avg_promoted()->padded_average(),
  1258                 _avg_pretenured->padded_average(),
  1259                 tenuring_threshold, target_size);
  1260     tty->cr();
  1263   set_survivor_size(target_size);
  1265   return tenuring_threshold;
  1268 void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
  1269                                            size_t survived,
  1270                                            size_t promoted) {
  1271   // Update averages
  1272   if (!is_survivor_overflow) {
  1273     // Keep running averages on how much survived
  1274     _avg_survived->sample(survived);
  1275   } else {
  1276     size_t survived_guess = survived + promoted;
  1277     _avg_survived->sample(survived_guess);
  1279   avg_promoted()->sample(promoted + _avg_pretenured->padded_average());
  1281   if (PrintAdaptiveSizePolicy) {
  1282     gclog_or_tty->print(
  1283                   "AdaptiveSizePolicy::compute_survivor_space_size_and_thresh:"
  1284                   "  survived: "  SIZE_FORMAT
  1285                   "  promoted: "  SIZE_FORMAT
  1286                   "  overflow: %s",
  1287                   survived, promoted, is_survivor_overflow ? "true" : "false");
  1291 bool PSAdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st)
  1292   const {
  1294   if (!UseAdaptiveSizePolicy) return false;
  1296   return AdaptiveSizePolicy::print_adaptive_size_policy_on(
  1297                           st,
  1298                           PSScavenge::tenuring_threshold());

mercurial