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
37class elapsedTimer;
38
39class 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 };
50 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
180 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.
191 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
206 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.
217 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.
234 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.
251 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
257 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
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);
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
281 int change_old_gen_for_throughput() const {
282 return _change_old_gen_for_throughput;
283 }
284 void set_change_old_gen_for_throughput(int v) {
285 _change_old_gen_for_throughput = v;
286 }
287 int change_young_gen_for_throughput() const {
288 return _change_young_gen_for_throughput;
289 }
290 void set_change_young_gen_for_throughput(int v) {
291 _change_young_gen_for_throughput = v;
292 }
293
294 int change_old_gen_for_maj_pauses() const {
295 return _change_old_gen_for_maj_pauses;
296 }
297 void set_change_old_gen_for_maj_pauses(int v) {
298 _change_old_gen_for_maj_pauses = v;
299 }
300
301 bool decrement_tenuring_threshold_for_gc_cost() const {
302 return _decrement_tenuring_threshold_for_gc_cost;
303 }
304 void set_decrement_tenuring_threshold_for_gc_cost(bool v) {
305 _decrement_tenuring_threshold_for_gc_cost = v;
306 }
307 bool increment_tenuring_threshold_for_gc_cost() const {
308 return _increment_tenuring_threshold_for_gc_cost;
309 }
310 void set_increment_tenuring_threshold_for_gc_cost(bool v) {
311 _increment_tenuring_threshold_for_gc_cost = v;
312 }
313 bool decrement_tenuring_threshold_for_survivor_limit() const {
314 return _decrement_tenuring_threshold_for_survivor_limit;
315 }
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
329 bool is_gc_cms_adaptive_size_policy() {
330 return kind() == _gc_cms_adaptive_size_policy;
331 }
332 bool is_gc_ps_adaptive_size_policy() {
333 return kind() == _gc_ps_adaptive_size_policy;
334 }
335
336 AdaptivePaddedAverage* avg_minor_pause() const { return _avg_minor_pause; }
337 AdaptiveWeightedAverage* avg_minor_interval() const {
338 return _avg_minor_interval;
339 }
340 AdaptiveWeightedAverage* avg_minor_gc_cost() const {
341 return _avg_minor_gc_cost;
342 }
343
344 AdaptiveWeightedAverage* avg_major_gc_cost() const {
345 return _avg_major_gc_cost;
346 }
347
348 AdaptiveWeightedAverage* avg_young_live() const { return _avg_young_live; }
349 AdaptiveWeightedAverage* avg_eden_live() const { return _avg_eden_live; }
350 AdaptiveWeightedAverage* avg_old_live() const { return _avg_old_live; }
351
352 AdaptivePaddedAverage* avg_survived() const { return _avg_survived; }
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);
360 virtual LinearLeastSquareFit* minor_pause_old_estimator() const {
361 return _minor_pause_old_estimator;
362 }
363
364 LinearLeastSquareFit* minor_pause_young_estimator() {
365 return _minor_pause_young_estimator;
366 }
367 LinearLeastSquareFit* minor_collection_estimator() {
368 return _minor_collection_estimator;
369 }
370
371 LinearLeastSquareFit* major_collection_estimator() {
372 return _major_collection_estimator;
373 }
374
375 float minor_pause_young_slope() {
376 return _minor_pause_young_estimator->slope();
377 }
378
379 float minor_collection_slope() { return _minor_collection_estimator->slope();}
380 float major_collection_slope() { return _major_collection_estimator->slope();}
381
382 float minor_pause_old_slope() {
383 return _minor_pause_old_estimator->slope();
384 }
385
386 void set_eden_size(size_t new_size) {
387 _eden_size = new_size;
388 }
389 void set_survivor_size(size_t new_size) {
390 _survivor_size = new_size;
391 }
392
393 size_t calculated_eden_size_in_bytes() const {
394 return _eden_size;
395 }
396
397 size_t calculated_promo_size_in_bytes() const {
398 return _promo_size;
399 }
400
401 size_t calculated_survivor_size_in_bytes() const {
402 return _survivor_size;
403 }
404
405 bool gc_overhead_limit_exceeded() {
406 return _overhead_checker.gc_overhead_limit_exceeded();
407 }
408 void set_gc_overhead_limit_exceeded(bool v) {
409 _overhead_checker.set_gc_overhead_limit_exceeded(v);
410 }
411
412 bool gc_overhead_limit_near() {
413 return _overhead_checker.gc_overhead_limit_near();
414 }
415
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
422 int change_young_gen_for_min_pauses() const {
423 return _change_young_gen_for_min_pauses;
424 }
425 void set_change_young_gen_for_min_pauses(int v) {
426 _change_young_gen_for_min_pauses = v;
427 }
428 void set_decrease_for_footprint(int v) { _decrease_for_footprint = v; }
429 int decrease_for_footprint() const { return _decrease_for_footprint; }
430 int decide_at_full_gc() { return _decide_at_full_gc; }
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
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
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