1 /*
2  * Copyright (c) 2004, 2019, 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  */
24 
25 #ifndef SHARE_GC_SHARED_ADAPTIVESIZEPOLICY_HPP
26 #define SHARE_GC_SHARED_ADAPTIVESIZEPOLICY_HPP
27 
28 #include "gc/shared/gcCause.hpp"
29 #include "gc/shared/gcOverheadChecker.hpp"
30 #include "gc/shared/gcUtil.hpp"
31 #include "memory/allocation.hpp"
32 
33 // This class keeps statistical information and computes the
34 // size of the heap.
35 
36 // Forward decls
37 class elapsedTimer;
38 
39 class AdaptiveSizePolicy : public CHeapObj<mtGC> {
40  friend class GCAdaptivePolicyCounters;
41  friend class PSGCAdaptivePolicyCounters;
42  friend class CMSGCAdaptivePolicyCounters;
43  protected:
44 
45   enum GCPolicyKind {
46     _gc_adaptive_size_policy,
47     _gc_ps_adaptive_size_policy,
48     _gc_cms_adaptive_size_policy
49   };
kind() const50   virtual GCPolicyKind kind() const { return _gc_adaptive_size_policy; }
51 
52   enum SizePolicyTrueValues {
53     decrease_old_gen_for_throughput_true = -7,
54     decrease_young_gen_for_througput_true = -6,
55 
56     increase_old_gen_for_min_pauses_true = -5,
57     decrease_old_gen_for_min_pauses_true = -4,
58     decrease_young_gen_for_maj_pauses_true = -3,
59     increase_young_gen_for_min_pauses_true = -2,
60     increase_old_gen_for_maj_pauses_true = -1,
61 
62     decrease_young_gen_for_min_pauses_true = 1,
63     decrease_old_gen_for_maj_pauses_true = 2,
64     increase_young_gen_for_maj_pauses_true = 3,
65 
66     increase_old_gen_for_throughput_true = 4,
67     increase_young_gen_for_througput_true = 5,
68 
69     decrease_young_gen_for_footprint_true = 6,
70     decrease_old_gen_for_footprint_true = 7,
71     decide_at_full_gc_true = 8
72   };
73 
74   // Goal for the fraction of the total time during which application
75   // threads run
76   const double _throughput_goal;
77 
78   // Last calculated sizes, in bytes, and aligned
79   size_t _eden_size;        // calculated eden free space in bytes
80   size_t _promo_size;       // calculated cms gen free space in bytes
81 
82   size_t _survivor_size;    // calculated survivor size in bytes
83 
84   // Support for UseGCOverheadLimit
85   GCOverheadChecker _overhead_checker;
86 
87   // Minor collection timers used to determine both
88   // pause and interval times for collections
89   static elapsedTimer _minor_timer;
90 
91   // Major collection timers, used to determine both
92   // pause and interval times for collections
93   static elapsedTimer _major_timer;
94 
95   // Time statistics
96   AdaptivePaddedAverage*   _avg_minor_pause;
97   AdaptiveWeightedAverage* _avg_minor_interval;
98   AdaptiveWeightedAverage* _avg_minor_gc_cost;
99 
100   AdaptiveWeightedAverage* _avg_major_interval;
101   AdaptiveWeightedAverage* _avg_major_gc_cost;
102 
103   // Footprint statistics
104   AdaptiveWeightedAverage* _avg_young_live;
105   AdaptiveWeightedAverage* _avg_eden_live;
106   AdaptiveWeightedAverage* _avg_old_live;
107 
108   // Statistics for survivor space calculation for young generation
109   AdaptivePaddedAverage*   _avg_survived;
110 
111   // Objects that have been directly allocated in the old generation
112   AdaptivePaddedNoZeroDevAverage*   _avg_pretenured;
113 
114   // Variable for estimating the major and minor pause times.
115   // These variables represent linear least-squares fits of
116   // the data.
117   //   minor pause time vs. old gen size
118   LinearLeastSquareFit* _minor_pause_old_estimator;
119   //   minor pause time vs. young gen size
120   LinearLeastSquareFit* _minor_pause_young_estimator;
121 
122   // Variables for estimating the major and minor collection costs
123   //   minor collection time vs. young gen size
124   LinearLeastSquareFit* _minor_collection_estimator;
125   //   major collection time vs. cms gen size
126   LinearLeastSquareFit* _major_collection_estimator;
127 
128   // These record the most recent collection times.  They
129   // are available as an alternative to using the averages
130   // for making ergonomic decisions.
131   double _latest_minor_mutator_interval_seconds;
132 
133   // Allowed difference between major and minor GC times, used
134   // for computing tenuring_threshold
135   const double _threshold_tolerance_percent;
136 
137   const double _gc_pause_goal_sec; // Goal for maximum GC pause
138 
139   // Flag indicating that the adaptive policy is ready to use
140   bool _young_gen_policy_is_ready;
141 
142   // Decrease/increase the young generation for minor pause time
143   int _change_young_gen_for_min_pauses;
144 
145   // Decrease/increase the old generation for major pause time
146   int _change_old_gen_for_maj_pauses;
147 
148   //   change old generation for throughput
149   int _change_old_gen_for_throughput;
150 
151   //   change young generation for throughput
152   int _change_young_gen_for_throughput;
153 
154   // Flag indicating that the policy would
155   //   increase the tenuring threshold because of the total major GC cost
156   //   is greater than the total minor GC cost
157   bool _increment_tenuring_threshold_for_gc_cost;
158   //   decrease the tenuring threshold because of the the total minor GC
159   //   cost is greater than the total major GC cost
160   bool _decrement_tenuring_threshold_for_gc_cost;
161   //   decrease due to survivor size limit
162   bool _decrement_tenuring_threshold_for_survivor_limit;
163 
164   //   decrease generation sizes for footprint
165   int _decrease_for_footprint;
166 
167   // Set if the ergonomic decisions were made at a full GC.
168   int _decide_at_full_gc;
169 
170   // Changing the generation sizing depends on the data that is
171   // gathered about the effects of changes on the pause times and
172   // throughput.  These variable count the number of data points
173   // gathered.  The policy may use these counters as a threshold
174   // for reliable data.
175   julong _young_gen_change_for_minor_throughput;
176   julong _old_gen_change_for_major_throughput;
177 
178   // Accessors
179 
gc_pause_goal_sec() const180   double gc_pause_goal_sec() const { return _gc_pause_goal_sec; }
181   // The value returned is unitless:  it's the proportion of time
182   // spent in a particular collection type.
183   // An interval time will be 0.0 if a collection type hasn't occurred yet.
184   // The 1.4.2 implementation put a floor on the values of major_gc_cost
185   // and minor_gc_cost.  This was useful because of the way major_gc_cost
186   // and minor_gc_cost was used in calculating the sizes of the generations.
187   // Do not use a floor in this implementation because any finite value
188   // will put a limit on the throughput that can be achieved and any
189   // throughput goal above that limit will drive the generations sizes
190   // to extremes.
major_gc_cost() const191   double major_gc_cost() const {
192     return MAX2(0.0F, _avg_major_gc_cost->average());
193   }
194 
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 
minor_gc_cost() const206   double minor_gc_cost() const {
207     return MAX2(0.0F, _avg_minor_gc_cost->average());
208   }
209 
210   // Because we're dealing with averages, gc_cost() can be
211   // larger than 1.0 if just the sum of the minor cost the
212   // the major cost is used.  Worse than that is the
213   // fact that the minor cost and the major cost each
214   // tend toward 1.0 in the extreme of high GC costs.
215   // Limit the value of gc_cost to 1.0 so that the mutator
216   // cost stays non-negative.
gc_cost() const217   virtual double gc_cost() const {
218     double result = MIN2(1.0, minor_gc_cost() + major_gc_cost());
219     assert(result >= 0.0, "Both minor and major costs are non-negative");
220     return result;
221   }
222 
223   // Elapsed time since the last major collection.
224   virtual double time_since_major_gc() const;
225 
226   // Average interval between major collections to be used
227   // in calculating the decaying major GC cost.  An overestimate
228   // of this time would be a conservative estimate because
229   // this time is used to decide if the major GC cost
230   // should be decayed (i.e., if the time since the last
231   // major GC is long compared to the time returned here,
232   // then the major GC cost will be decayed).  See the
233   // implementations for the specifics.
major_gc_interval_average_for_decay() const234   virtual double major_gc_interval_average_for_decay() const {
235     return _avg_major_interval->average();
236   }
237 
238   // Return the cost of the GC where the major GC cost
239   // has been decayed based on the time since the last
240   // major collection.
241   double decaying_gc_cost() const;
242 
243   // Decay the major GC cost.  Use this only for decisions on
244   // whether to adjust, not to determine by how much to adjust.
245   // This approximation is crude and may not be good enough for the
246   // latter.
247   double decaying_major_gc_cost() const;
248 
249   // Return the mutator cost using the decayed
250   // GC cost.
adjusted_mutator_cost() const251   double adjusted_mutator_cost() const {
252     double result = 1.0 - decaying_gc_cost();
253     assert(result >= 0.0, "adjusted mutator cost calculation is incorrect");
254     return result;
255   }
256 
mutator_cost() const257   virtual double mutator_cost() const {
258     double result = 1.0 - gc_cost();
259     assert(result >= 0.0, "mutator cost calculation is incorrect");
260     return result;
261   }
262 
263 
young_gen_policy_is_ready()264   bool young_gen_policy_is_ready() { return _young_gen_policy_is_ready; }
265 
266   void update_minor_pause_young_estimator(double minor_pause_in_ms);
update_minor_pause_old_estimator(double minor_pause_in_ms)267   virtual void update_minor_pause_old_estimator(double minor_pause_in_ms) {
268     // This is not meaningful for all policies but needs to be present
269     // to use minor_collection_end() in its current form.
270   }
271 
272   virtual size_t eden_increment(size_t cur_eden);
273   virtual size_t eden_increment(size_t cur_eden, uint percent_change);
274   virtual size_t eden_decrement(size_t cur_eden);
275   virtual size_t promo_increment(size_t cur_eden);
276   virtual size_t promo_increment(size_t cur_eden, uint percent_change);
277   virtual size_t promo_decrement(size_t cur_eden);
278 
279   virtual void clear_generation_free_space_flags();
280 
change_old_gen_for_throughput() const281   int change_old_gen_for_throughput() const {
282     return _change_old_gen_for_throughput;
283   }
set_change_old_gen_for_throughput(int v)284   void set_change_old_gen_for_throughput(int v) {
285     _change_old_gen_for_throughput = v;
286   }
change_young_gen_for_throughput() const287   int change_young_gen_for_throughput() const {
288     return _change_young_gen_for_throughput;
289   }
set_change_young_gen_for_throughput(int v)290   void set_change_young_gen_for_throughput(int v) {
291     _change_young_gen_for_throughput = v;
292   }
293 
change_old_gen_for_maj_pauses() const294   int change_old_gen_for_maj_pauses() const {
295     return _change_old_gen_for_maj_pauses;
296   }
set_change_old_gen_for_maj_pauses(int v)297   void set_change_old_gen_for_maj_pauses(int v) {
298     _change_old_gen_for_maj_pauses = v;
299   }
300 
decrement_tenuring_threshold_for_gc_cost() const301   bool decrement_tenuring_threshold_for_gc_cost() const {
302     return _decrement_tenuring_threshold_for_gc_cost;
303   }
set_decrement_tenuring_threshold_for_gc_cost(bool v)304   void set_decrement_tenuring_threshold_for_gc_cost(bool v) {
305     _decrement_tenuring_threshold_for_gc_cost = v;
306   }
increment_tenuring_threshold_for_gc_cost() const307   bool increment_tenuring_threshold_for_gc_cost() const {
308     return _increment_tenuring_threshold_for_gc_cost;
309   }
set_increment_tenuring_threshold_for_gc_cost(bool v)310   void set_increment_tenuring_threshold_for_gc_cost(bool v) {
311     _increment_tenuring_threshold_for_gc_cost = v;
312   }
decrement_tenuring_threshold_for_survivor_limit() const313   bool decrement_tenuring_threshold_for_survivor_limit() const {
314     return _decrement_tenuring_threshold_for_survivor_limit;
315   }
set_decrement_tenuring_threshold_for_survivor_limit(bool v)316   void set_decrement_tenuring_threshold_for_survivor_limit(bool v) {
317     _decrement_tenuring_threshold_for_survivor_limit = v;
318   }
319   // Return true if the policy suggested a change.
320   bool tenuring_threshold_change() const;
321 
322  public:
323   AdaptiveSizePolicy(size_t init_eden_size,
324                      size_t init_promo_size,
325                      size_t init_survivor_size,
326                      double gc_pause_goal_sec,
327                      uint gc_cost_ratio);
328 
is_gc_cms_adaptive_size_policy()329   bool is_gc_cms_adaptive_size_policy() {
330     return kind() == _gc_cms_adaptive_size_policy;
331   }
is_gc_ps_adaptive_size_policy()332   bool is_gc_ps_adaptive_size_policy() {
333     return kind() == _gc_ps_adaptive_size_policy;
334   }
335 
avg_minor_pause() const336   AdaptivePaddedAverage*   avg_minor_pause() const { return _avg_minor_pause; }
avg_minor_interval() const337   AdaptiveWeightedAverage* avg_minor_interval() const {
338     return _avg_minor_interval;
339   }
avg_minor_gc_cost() const340   AdaptiveWeightedAverage* avg_minor_gc_cost() const {
341     return _avg_minor_gc_cost;
342   }
343 
avg_major_gc_cost() const344   AdaptiveWeightedAverage* avg_major_gc_cost() const {
345     return _avg_major_gc_cost;
346   }
347 
avg_young_live() const348   AdaptiveWeightedAverage* avg_young_live() const { return _avg_young_live; }
avg_eden_live() const349   AdaptiveWeightedAverage* avg_eden_live() const { return _avg_eden_live; }
avg_old_live() const350   AdaptiveWeightedAverage* avg_old_live() const { return _avg_old_live; }
351 
avg_survived() const352   AdaptivePaddedAverage*  avg_survived() const { return _avg_survived; }
avg_pretenured()353   AdaptivePaddedNoZeroDevAverage*  avg_pretenured() { return _avg_pretenured; }
354 
355   // Methods indicating events of interest to the adaptive size policy,
356   // called by GC algorithms. It is the responsibility of users of this
357   // policy to call these methods at the correct times!
358   virtual void minor_collection_begin();
359   virtual void minor_collection_end(GCCause::Cause gc_cause);
minor_pause_old_estimator() const360   virtual LinearLeastSquareFit* minor_pause_old_estimator() const {
361     return _minor_pause_old_estimator;
362   }
363 
minor_pause_young_estimator()364   LinearLeastSquareFit* minor_pause_young_estimator() {
365     return _minor_pause_young_estimator;
366   }
minor_collection_estimator()367   LinearLeastSquareFit* minor_collection_estimator() {
368     return _minor_collection_estimator;
369   }
370 
major_collection_estimator()371   LinearLeastSquareFit* major_collection_estimator() {
372     return _major_collection_estimator;
373   }
374 
minor_pause_young_slope()375   float minor_pause_young_slope() {
376     return _minor_pause_young_estimator->slope();
377   }
378 
minor_collection_slope()379   float minor_collection_slope() { return _minor_collection_estimator->slope();}
major_collection_slope()380   float major_collection_slope() { return _major_collection_estimator->slope();}
381 
minor_pause_old_slope()382   float minor_pause_old_slope() {
383     return _minor_pause_old_estimator->slope();
384   }
385 
set_eden_size(size_t new_size)386   void set_eden_size(size_t new_size) {
387     _eden_size = new_size;
388   }
set_survivor_size(size_t new_size)389   void set_survivor_size(size_t new_size) {
390     _survivor_size = new_size;
391   }
392 
calculated_eden_size_in_bytes() const393   size_t calculated_eden_size_in_bytes() const {
394     return _eden_size;
395   }
396 
calculated_promo_size_in_bytes() const397   size_t calculated_promo_size_in_bytes() const {
398     return _promo_size;
399   }
400 
calculated_survivor_size_in_bytes() const401   size_t calculated_survivor_size_in_bytes() const {
402     return _survivor_size;
403   }
404 
gc_overhead_limit_exceeded()405   bool gc_overhead_limit_exceeded() {
406     return _overhead_checker.gc_overhead_limit_exceeded();
407   }
set_gc_overhead_limit_exceeded(bool v)408   void set_gc_overhead_limit_exceeded(bool v) {
409     _overhead_checker.set_gc_overhead_limit_exceeded(v);
410   }
411 
gc_overhead_limit_near()412   bool gc_overhead_limit_near() {
413     return _overhead_checker.gc_overhead_limit_near();
414   }
415 
reset_gc_overhead_limit_count()416   void reset_gc_overhead_limit_count() {
417     _overhead_checker.reset_gc_overhead_limit_count();
418   }
419   // accessors for flags recording the decisions to resize the
420   // generations to meet the pause goal.
421 
change_young_gen_for_min_pauses() const422   int change_young_gen_for_min_pauses() const {
423     return _change_young_gen_for_min_pauses;
424   }
set_change_young_gen_for_min_pauses(int v)425   void set_change_young_gen_for_min_pauses(int v) {
426     _change_young_gen_for_min_pauses = v;
427   }
set_decrease_for_footprint(int v)428   void set_decrease_for_footprint(int v) { _decrease_for_footprint = v; }
decrease_for_footprint() const429   int decrease_for_footprint() const { return _decrease_for_footprint; }
decide_at_full_gc()430   int decide_at_full_gc() { return _decide_at_full_gc; }
set_decide_at_full_gc(int v)431   void set_decide_at_full_gc(int v) { _decide_at_full_gc = v; }
432 
433   // Check the conditions for an out-of-memory due to excessive GC time.
434   // Set _gc_overhead_limit_exceeded if all the conditions have been met.
435   void check_gc_overhead_limit(size_t eden_live,
436                                size_t max_old_gen_size,
437                                size_t max_eden_size,
438                                bool   is_full_gc,
439                                GCCause::Cause gc_cause,
440                                SoftRefPolicy* soft_ref_policy);
441 
should_update_promo_stats(GCCause::Cause cause)442   static bool should_update_promo_stats(GCCause::Cause cause) {
443     return ((GCCause::is_user_requested_gc(cause)  &&
444                UseAdaptiveSizePolicyWithSystemGC) ||
445             GCCause::is_tenured_allocation_failure_gc(cause));
446   }
447 
should_update_eden_stats(GCCause::Cause cause)448   static bool should_update_eden_stats(GCCause::Cause cause) {
449     return ((GCCause::is_user_requested_gc(cause)  &&
450                UseAdaptiveSizePolicyWithSystemGC) ||
451             GCCause::is_allocation_failure_gc(cause));
452   }
453 
454   // Printing support
455   virtual bool print() const;
456   void print_tenuring_threshold(uint new_tenuring_threshold) const;
457 };
458 
459 #endif // SHARE_GC_SHARED_ADAPTIVESIZEPOLICY_HPP
460