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