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

Thu, 27 May 2010 19:08:38 -0700

author
trims
date
Thu, 27 May 2010 19:08:38 -0700
changeset 1907
c18cbe5936b8
parent 1822
0bfd3fb24150
child 2314
f95d63e2154a
permissions
-rw-r--r--

6941466: Oracle rebranding changes for Hotspot repositories
Summary: Change all the Sun copyrights to Oracle copyright
Reviewed-by: ohair

     1 /*
     2  * Copyright (c) 2004, 2010, 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 // This class keeps statistical information and computes the
    26 // size of the heap.
    28 // Forward decls
    29 class elapsedTimer;
    30 class CollectorPolicy;
    32 class AdaptiveSizePolicy : public CHeapObj {
    33  friend class GCAdaptivePolicyCounters;
    34  friend class PSGCAdaptivePolicyCounters;
    35  friend class CMSGCAdaptivePolicyCounters;
    36  protected:
    38   enum GCPolicyKind {
    39     _gc_adaptive_size_policy,
    40     _gc_ps_adaptive_size_policy,
    41     _gc_cms_adaptive_size_policy
    42   };
    43   virtual GCPolicyKind kind() const { return _gc_adaptive_size_policy; }
    45   enum SizePolicyTrueValues {
    46     decrease_old_gen_for_throughput_true = -7,
    47     decrease_young_gen_for_througput_true = -6,
    49     increase_old_gen_for_min_pauses_true = -5,
    50     decrease_old_gen_for_min_pauses_true = -4,
    51     decrease_young_gen_for_maj_pauses_true = -3,
    52     increase_young_gen_for_min_pauses_true = -2,
    53     increase_old_gen_for_maj_pauses_true = -1,
    55     decrease_young_gen_for_min_pauses_true = 1,
    56     decrease_old_gen_for_maj_pauses_true = 2,
    57     increase_young_gen_for_maj_pauses_true = 3,
    59     increase_old_gen_for_throughput_true = 4,
    60     increase_young_gen_for_througput_true = 5,
    62     decrease_young_gen_for_footprint_true = 6,
    63     decrease_old_gen_for_footprint_true = 7,
    64     decide_at_full_gc_true = 8
    65   };
    67   // Goal for the fraction of the total time during which application
    68   // threads run.
    69   const double _throughput_goal;
    71   // Last calculated sizes, in bytes, and aligned
    72   size_t _eden_size;        // calculated eden free space in bytes
    73   size_t _promo_size;       // calculated cms gen free space in bytes
    75   size_t _survivor_size;    // calculated survivor size in bytes
    77   // This is a hint for the heap:  we've detected that gc times
    78   // are taking longer than GCTimeLimit allows.
    79   bool _gc_overhead_limit_exceeded;
    80   // Use for diagnostics only.  If UseGCOverheadLimit is false,
    81   // this variable is still set.
    82   bool _print_gc_overhead_limit_would_be_exceeded;
    83   // Count of consecutive GC that have exceeded the
    84   // GC time limit criterion.
    85   uint _gc_overhead_limit_count;
    86   // This flag signals that GCTimeLimit is being exceeded
    87   // but may not have done so for the required number of consequetive
    88   // collections.
    90   // Minor collection timers used to determine both
    91   // pause and interval times for collections.
    92   static elapsedTimer _minor_timer;
    94   // Major collection timers, used to determine both
    95   // pause and interval times for collections
    96   static elapsedTimer _major_timer;
    98   // Time statistics
    99   AdaptivePaddedAverage*   _avg_minor_pause;
   100   AdaptiveWeightedAverage* _avg_minor_interval;
   101   AdaptiveWeightedAverage* _avg_minor_gc_cost;
   103   AdaptiveWeightedAverage* _avg_major_interval;
   104   AdaptiveWeightedAverage* _avg_major_gc_cost;
   106   // Footprint statistics
   107   AdaptiveWeightedAverage* _avg_young_live;
   108   AdaptiveWeightedAverage* _avg_eden_live;
   109   AdaptiveWeightedAverage* _avg_old_live;
   111   // Statistics for survivor space calculation for young generation
   112   AdaptivePaddedAverage*   _avg_survived;
   114   // Objects that have been directly allocated in the old generation.
   115   AdaptivePaddedNoZeroDevAverage*   _avg_pretenured;
   117   // Variable for estimating the major and minor pause times.
   118   // These variables represent linear least-squares fits of
   119   // the data.
   120   //   minor pause time vs. old gen size
   121   LinearLeastSquareFit* _minor_pause_old_estimator;
   122   //   minor pause time vs. young gen size
   123   LinearLeastSquareFit* _minor_pause_young_estimator;
   125   // Variables for estimating the major and minor collection costs
   126   //   minor collection time vs. young gen size
   127   LinearLeastSquareFit* _minor_collection_estimator;
   128   //   major collection time vs. cms gen size
   129   LinearLeastSquareFit* _major_collection_estimator;
   131   // These record the most recent collection times.  They
   132   // are available as an alternative to using the averages
   133   // for making ergonomic decisions.
   134   double _latest_minor_mutator_interval_seconds;
   136   // Allowed difference between major and minor gc times, used
   137   // for computing tenuring_threshold.
   138   const double _threshold_tolerance_percent;
   140   const double _gc_pause_goal_sec; // goal for maximum gc pause
   142   // Flag indicating that the adaptive policy is ready to use
   143   bool _young_gen_policy_is_ready;
   145   // decrease/increase the young generation for minor pause time
   146   int _change_young_gen_for_min_pauses;
   148   // decrease/increase the old generation for major pause time
   149   int _change_old_gen_for_maj_pauses;
   151   //   change old geneneration for throughput
   152   int _change_old_gen_for_throughput;
   154   //   change young generation for throughput
   155   int _change_young_gen_for_throughput;
   157   // Flag indicating that the policy would
   158   //   increase the tenuring threshold because of the total major gc cost
   159   //   is greater than the total minor gc cost
   160   bool _increment_tenuring_threshold_for_gc_cost;
   161   //   decrease the tenuring threshold because of the the total minor gc
   162   //   cost is greater than the total major gc cost
   163   bool _decrement_tenuring_threshold_for_gc_cost;
   164   //   decrease due to survivor size limit
   165   bool _decrement_tenuring_threshold_for_survivor_limit;
   167   //   decrease generation sizes for footprint
   168   int _decrease_for_footprint;
   170   // Set if the ergonomic decisions were made at a full GC.
   171   int _decide_at_full_gc;
   173   // Changing the generation sizing depends on the data that is
   174   // gathered about the effects of changes on the pause times and
   175   // throughput.  These variable count the number of data points
   176   // gathered.  The policy may use these counters as a threshhold
   177   // for reliable data.
   178   julong _young_gen_change_for_minor_throughput;
   179   julong _old_gen_change_for_major_throughput;
   181   // Accessors
   183   double gc_pause_goal_sec() const { return _gc_pause_goal_sec; }
   184   // The value returned is unitless:  it's the proportion of time
   185   // spent in a particular collection type.
   186   // An interval time will be 0.0 if a collection type hasn't occurred yet.
   187   // The 1.4.2 implementation put a floor on the values of major_gc_cost
   188   // and minor_gc_cost.  This was useful because of the way major_gc_cost
   189   // and minor_gc_cost was used in calculating the sizes of the generations.
   190   // Do not use a floor in this implementation because any finite value
   191   // will put a limit on the throughput that can be achieved and any
   192   // throughput goal above that limit will drive the generations sizes
   193   // to extremes.
   194   double major_gc_cost() const {
   195     return MAX2(0.0F, _avg_major_gc_cost->average());
   196   }
   198   // The value returned is unitless:  it's the proportion of time
   199   // spent in a particular collection type.
   200   // An interval time will be 0.0 if a collection type hasn't occurred yet.
   201   // The 1.4.2 implementation put a floor on the values of major_gc_cost
   202   // and minor_gc_cost.  This was useful because of the way major_gc_cost
   203   // and minor_gc_cost was used in calculating the sizes of the generations.
   204   // Do not use a floor in this implementation because any finite value
   205   // will put a limit on the throughput that can be achieved and any
   206   // throughput goal above that limit will drive the generations sizes
   207   // to extremes.
   209   double minor_gc_cost() const {
   210     return MAX2(0.0F, _avg_minor_gc_cost->average());
   211   }
   213   // Because we're dealing with averages, gc_cost() can be
   214   // larger than 1.0 if just the sum of the minor cost the
   215   // the major cost is used.  Worse than that is the
   216   // fact that the minor cost and the major cost each
   217   // tend toward 1.0 in the extreme of high gc costs.
   218   // Limit the value of gc_cost to 1.0 so that the mutator
   219   // cost stays non-negative.
   220   virtual double gc_cost() const {
   221     double result = MIN2(1.0, minor_gc_cost() + major_gc_cost());
   222     assert(result >= 0.0, "Both minor and major costs are non-negative");
   223     return result;
   224   }
   226   // Elapsed time since the last major collection.
   227   virtual double time_since_major_gc() const;
   229   // Average interval between major collections to be used
   230   // in calculating the decaying major gc cost.  An overestimate
   231   // of this time would be a conservative estimate because
   232   // this time is used to decide if the major GC cost
   233   // should be decayed (i.e., if the time since the last
   234   // major gc is long compared to the time returned here,
   235   // then the major GC cost will be decayed).  See the
   236   // implementations for the specifics.
   237   virtual double major_gc_interval_average_for_decay() const {
   238     return _avg_major_interval->average();
   239   }
   241   // Return the cost of the GC where the major gc cost
   242   // has been decayed based on the time since the last
   243   // major collection.
   244   double decaying_gc_cost() const;
   246   // Decay the major gc cost.  Use this only for decisions on
   247   // whether to adjust, not to determine by how much to adjust.
   248   // This approximation is crude and may not be good enough for the
   249   // latter.
   250   double decaying_major_gc_cost() const;
   252   // Return the mutator cost using the decayed
   253   // GC cost.
   254   double adjusted_mutator_cost() const {
   255     double result = 1.0 - decaying_gc_cost();
   256     assert(result >= 0.0, "adjusted mutator cost calculation is incorrect");
   257     return result;
   258   }
   260   virtual double mutator_cost() const {
   261     double result = 1.0 - gc_cost();
   262     assert(result >= 0.0, "mutator cost calculation is incorrect");
   263     return result;
   264   }
   267   bool young_gen_policy_is_ready() { return _young_gen_policy_is_ready; }
   269   void update_minor_pause_young_estimator(double minor_pause_in_ms);
   270   virtual void update_minor_pause_old_estimator(double minor_pause_in_ms) {
   271     // This is not meaningful for all policies but needs to be present
   272     // to use minor_collection_end() in its current form.
   273   }
   275   virtual size_t eden_increment(size_t cur_eden);
   276   virtual size_t eden_increment(size_t cur_eden, uint percent_change);
   277   virtual size_t eden_decrement(size_t cur_eden);
   278   virtual size_t promo_increment(size_t cur_eden);
   279   virtual size_t promo_increment(size_t cur_eden, uint percent_change);
   280   virtual size_t promo_decrement(size_t cur_eden);
   282   virtual void clear_generation_free_space_flags();
   284   int change_old_gen_for_throughput() const {
   285     return _change_old_gen_for_throughput;
   286   }
   287   void set_change_old_gen_for_throughput(int v) {
   288     _change_old_gen_for_throughput = v;
   289   }
   290   int change_young_gen_for_throughput() const {
   291     return _change_young_gen_for_throughput;
   292   }
   293   void set_change_young_gen_for_throughput(int v) {
   294     _change_young_gen_for_throughput = v;
   295   }
   297   int change_old_gen_for_maj_pauses() const {
   298     return _change_old_gen_for_maj_pauses;
   299   }
   300   void set_change_old_gen_for_maj_pauses(int v) {
   301     _change_old_gen_for_maj_pauses = v;
   302   }
   304   bool decrement_tenuring_threshold_for_gc_cost() const {
   305     return _decrement_tenuring_threshold_for_gc_cost;
   306   }
   307   void set_decrement_tenuring_threshold_for_gc_cost(bool v) {
   308     _decrement_tenuring_threshold_for_gc_cost = v;
   309   }
   310   bool increment_tenuring_threshold_for_gc_cost() const {
   311     return _increment_tenuring_threshold_for_gc_cost;
   312   }
   313   void set_increment_tenuring_threshold_for_gc_cost(bool v) {
   314     _increment_tenuring_threshold_for_gc_cost = v;
   315   }
   316   bool decrement_tenuring_threshold_for_survivor_limit() const {
   317     return _decrement_tenuring_threshold_for_survivor_limit;
   318   }
   319   void set_decrement_tenuring_threshold_for_survivor_limit(bool v) {
   320     _decrement_tenuring_threshold_for_survivor_limit = v;
   321   }
   322   // Return true if the policy suggested a change.
   323   bool tenuring_threshold_change() const;
   325  public:
   326   AdaptiveSizePolicy(size_t init_eden_size,
   327                      size_t init_promo_size,
   328                      size_t init_survivor_size,
   329                      double gc_pause_goal_sec,
   330                      uint gc_cost_ratio);
   332   bool is_gc_cms_adaptive_size_policy() {
   333     return kind() == _gc_cms_adaptive_size_policy;
   334   }
   335   bool is_gc_ps_adaptive_size_policy() {
   336     return kind() == _gc_ps_adaptive_size_policy;
   337   }
   339   AdaptivePaddedAverage*   avg_minor_pause() const { return _avg_minor_pause; }
   340   AdaptiveWeightedAverage* avg_minor_interval() const {
   341     return _avg_minor_interval;
   342   }
   343   AdaptiveWeightedAverage* avg_minor_gc_cost() const {
   344     return _avg_minor_gc_cost;
   345   }
   347   AdaptiveWeightedAverage* avg_major_gc_cost() const {
   348     return _avg_major_gc_cost;
   349   }
   351   AdaptiveWeightedAverage* avg_young_live() const { return _avg_young_live; }
   352   AdaptiveWeightedAverage* avg_eden_live() const { return _avg_eden_live; }
   353   AdaptiveWeightedAverage* avg_old_live() const { return _avg_old_live; }
   355   AdaptivePaddedAverage*  avg_survived() const { return _avg_survived; }
   356   AdaptivePaddedNoZeroDevAverage*  avg_pretenured() { return _avg_pretenured; }
   358   // Methods indicating events of interest to the adaptive size policy,
   359   // called by GC algorithms. It is the responsibility of users of this
   360   // policy to call these methods at the correct times!
   361   virtual void minor_collection_begin();
   362   virtual void minor_collection_end(GCCause::Cause gc_cause);
   363   virtual LinearLeastSquareFit* minor_pause_old_estimator() const {
   364     return _minor_pause_old_estimator;
   365   }
   367   LinearLeastSquareFit* minor_pause_young_estimator() {
   368     return _minor_pause_young_estimator;
   369   }
   370   LinearLeastSquareFit* minor_collection_estimator() {
   371     return _minor_collection_estimator;
   372   }
   374   LinearLeastSquareFit* major_collection_estimator() {
   375     return _major_collection_estimator;
   376   }
   378   float minor_pause_young_slope() {
   379     return _minor_pause_young_estimator->slope();
   380   }
   382   float minor_collection_slope() { return _minor_collection_estimator->slope();}
   383   float major_collection_slope() { return _major_collection_estimator->slope();}
   385   float minor_pause_old_slope() {
   386     return _minor_pause_old_estimator->slope();
   387   }
   389   void set_eden_size(size_t new_size) {
   390     _eden_size = new_size;
   391   }
   392   void set_survivor_size(size_t new_size) {
   393     _survivor_size = new_size;
   394   }
   396   size_t calculated_eden_size_in_bytes() const {
   397     return _eden_size;
   398   }
   400   size_t calculated_promo_size_in_bytes() const {
   401     return _promo_size;
   402   }
   404   size_t calculated_survivor_size_in_bytes() const {
   405     return _survivor_size;
   406   }
   408   // This is a hint for the heap:  we've detected that gc times
   409   // are taking longer than GCTimeLimit allows.
   410   // Most heaps will choose to throw an OutOfMemoryError when
   411   // this occurs but it is up to the heap to request this information
   412   // of the policy
   413   bool gc_overhead_limit_exceeded() {
   414     return _gc_overhead_limit_exceeded;
   415   }
   416   void set_gc_overhead_limit_exceeded(bool v) {
   417     _gc_overhead_limit_exceeded = v;
   418   }
   420   // Tests conditions indicate the GC overhead limit is being approached.
   421   bool gc_overhead_limit_near() {
   422     return gc_overhead_limit_count() >=
   423         (AdaptiveSizePolicyGCTimeLimitThreshold - 1);
   424   }
   425   uint gc_overhead_limit_count() { return _gc_overhead_limit_count; }
   426   void reset_gc_overhead_limit_count() { _gc_overhead_limit_count = 0; }
   427   void inc_gc_overhead_limit_count() { _gc_overhead_limit_count++; }
   428   // accessors for flags recording the decisions to resize the
   429   // generations to meet the pause goal.
   431   int change_young_gen_for_min_pauses() const {
   432     return _change_young_gen_for_min_pauses;
   433   }
   434   void set_change_young_gen_for_min_pauses(int v) {
   435     _change_young_gen_for_min_pauses = v;
   436   }
   437   void set_decrease_for_footprint(int v) { _decrease_for_footprint = v; }
   438   int decrease_for_footprint() const { return _decrease_for_footprint; }
   439   int decide_at_full_gc() { return _decide_at_full_gc; }
   440   void set_decide_at_full_gc(int v) { _decide_at_full_gc = v; }
   442   // Check the conditions for an out-of-memory due to excessive GC time.
   443   // Set _gc_overhead_limit_exceeded if all the conditions have been met.
   444   void check_gc_overhead_limit(size_t young_live,
   445                                size_t eden_live,
   446                                size_t max_old_gen_size,
   447                                size_t max_eden_size,
   448                                bool   is_full_gc,
   449                                GCCause::Cause gc_cause,
   450                                CollectorPolicy* collector_policy);
   452   // Printing support
   453   virtual bool print_adaptive_size_policy_on(outputStream* st) const;
   454   bool print_adaptive_size_policy_on(outputStream* st, int
   455                                   tenuring_threshold) const;
   456 };
   458 // Class that can be used to print information about the
   459 // adaptive size policy at intervals specified by
   460 // AdaptiveSizePolicyOutputInterval.  Only print information
   461 // if an adaptive size policy is in use.
   462 class AdaptiveSizePolicyOutput : StackObj {
   463   AdaptiveSizePolicy* _size_policy;
   464   bool _do_print;
   465   bool print_test(uint count) {
   466     // A count of zero is a special value that indicates that the
   467     // interval test should be ignored.  An interval is of zero is
   468     // a special value that indicates that the interval test should
   469     // always fail (never do the print based on the interval test).
   470     return PrintGCDetails &&
   471            UseAdaptiveSizePolicy &&
   472            (UseParallelGC || UseConcMarkSweepGC) &&
   473            (AdaptiveSizePolicyOutputInterval > 0) &&
   474            ((count == 0) ||
   475              ((count % AdaptiveSizePolicyOutputInterval) == 0));
   476   }
   477  public:
   478   // The special value of a zero count can be used to ignore
   479   // the count test.
   480   AdaptiveSizePolicyOutput(uint count) {
   481     if (UseAdaptiveSizePolicy && (AdaptiveSizePolicyOutputInterval > 0)) {
   482       CollectedHeap* heap = Universe::heap();
   483       _size_policy = heap->size_policy();
   484       _do_print = print_test(count);
   485     } else {
   486       _size_policy = NULL;
   487       _do_print = false;
   488     }
   489   }
   490   AdaptiveSizePolicyOutput(AdaptiveSizePolicy* size_policy,
   491                            uint count) :
   492     _size_policy(size_policy) {
   493     if (UseAdaptiveSizePolicy && (AdaptiveSizePolicyOutputInterval > 0)) {
   494       _do_print = print_test(count);
   495     } else {
   496       _do_print = false;
   497     }
   498   }
   499   ~AdaptiveSizePolicyOutput() {
   500     if (_do_print) {
   501       assert(UseAdaptiveSizePolicy, "Should not be in use");
   502       _size_policy->print_adaptive_size_policy_on(gclog_or_tty);
   503     }
   504   }
   505 };

mercurial