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

Thu, 20 Sep 2012 09:52:56 -0700

author
johnc
date
Thu, 20 Sep 2012 09:52:56 -0700
changeset 4067
b2ef234911c9
parent 3900
d2a62e0f25eb
child 4129
22b8d3d181d9
permissions
-rw-r--r--

7190666: G1: assert(_unused == 0) failed: Inconsistency in PLAB stats
Summary: Reset the fields in ParGCAllocBuffer, that are used for accumulating values for the ResizePLAB sensors in PLABStats, to zero after flushing the values to the PLABStats fields. Flush PLABStats values only when retiring the final allocation buffers prior to disposing of a G1ParScanThreadState object, rather than when retiring every allocation buffer.
Reviewed-by: jwilhelm, jmasa, ysr

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

mercurial