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