1 /* 2 * Copyright (c) 2004, 2018, 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_VM_GC_SHARED_ADAPTIVESIZEPOLICY_HPP 26 #define SHARE_VM_GC_SHARED_ADAPTIVESIZEPOLICY_HPP 27 28 #include "gc/shared/gcCause.hpp" 29 #include "gc/shared/gcUtil.hpp" 30 #include "memory/allocation.hpp" 31 32 // This class keeps statistical information and computes the 33 // size of the heap. 34 35 // Forward decls 36 class elapsedTimer; 37 class SoftRefPolicy; 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 }; 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 // This is a hint for the heap: we've detected that GC times 85 // are taking longer than GCTimeLimit allows. 86 bool _gc_overhead_limit_exceeded; 87 // Use for diagnostics only. If UseGCOverheadLimit is false, 88 // this variable is still set. 89 bool _print_gc_overhead_limit_would_be_exceeded; 90 // Count of consecutive GC that have exceeded the 91 // GC time limit criterion 92 uint _gc_overhead_limit_count; 93 // This flag signals that GCTimeLimit is being exceeded 94 // but may not have done so for the required number of consecutive 95 // collections 96 97 // Minor collection timers used to determine both 98 // pause and interval times for collections 99 static elapsedTimer _minor_timer; 100 101 // Major collection timers, used to determine both 102 // pause and interval times for collections 103 static elapsedTimer _major_timer; 104 105 // Time statistics 106 AdaptivePaddedAverage* _avg_minor_pause; 107 AdaptiveWeightedAverage* _avg_minor_interval; 108 AdaptiveWeightedAverage* _avg_minor_gc_cost; 109 110 AdaptiveWeightedAverage* _avg_major_interval; 111 AdaptiveWeightedAverage* _avg_major_gc_cost; 112 113 // Footprint statistics 114 AdaptiveWeightedAverage* _avg_young_live; 115 AdaptiveWeightedAverage* _avg_eden_live; 116 AdaptiveWeightedAverage* _avg_old_live; 117 118 // Statistics for survivor space calculation for young generation 119 AdaptivePaddedAverage* _avg_survived; 120 121 // Objects that have been directly allocated in the old generation 122 AdaptivePaddedNoZeroDevAverage* _avg_pretenured; 123 124 // Variable for estimating the major and minor pause times. 125 // These variables represent linear least-squares fits of 126 // the data. 127 // minor pause time vs. old gen size 128 LinearLeastSquareFit* _minor_pause_old_estimator; 129 // minor pause time vs. young gen size 130 LinearLeastSquareFit* _minor_pause_young_estimator; 131 132 // Variables for estimating the major and minor collection costs 133 // minor collection time vs. young gen size 134 LinearLeastSquareFit* _minor_collection_estimator; 135 // major collection time vs. cms gen size 136 LinearLeastSquareFit* _major_collection_estimator; 137 138 // These record the most recent collection times. They 139 // are available as an alternative to using the averages 140 // for making ergonomic decisions. 141 double _latest_minor_mutator_interval_seconds; 142 143 // Allowed difference between major and minor GC times, used 144 // for computing tenuring_threshold 145 const double _threshold_tolerance_percent; 146 147 const double _gc_pause_goal_sec; // Goal for maximum GC pause 148 149 // Flag indicating that the adaptive policy is ready to use 150 bool _young_gen_policy_is_ready; 151 152 // Decrease/increase the young generation for minor pause time 153 int _change_young_gen_for_min_pauses; 154 155 // Decrease/increase the old generation for major pause time 156 int _change_old_gen_for_maj_pauses; 157 158 // change old generation for throughput 159 int _change_old_gen_for_throughput; 160 161 // change young generation for throughput 162 int _change_young_gen_for_throughput; 163 164 // Flag indicating that the policy would 165 // increase the tenuring threshold because of the total major GC cost 166 // is greater than the total minor GC cost 167 bool _increment_tenuring_threshold_for_gc_cost; 168 // decrease the tenuring threshold because of the the total minor GC 169 // cost is greater than the total major GC cost 170 bool _decrement_tenuring_threshold_for_gc_cost; 171 // decrease due to survivor size limit 172 bool _decrement_tenuring_threshold_for_survivor_limit; 173 174 // decrease generation sizes for footprint 175 int _decrease_for_footprint; 176 177 // Set if the ergonomic decisions were made at a full GC. 178 int _decide_at_full_gc; 179 180 // Changing the generation sizing depends on the data that is 181 // gathered about the effects of changes on the pause times and 182 // throughput. These variable count the number of data points 183 // gathered. The policy may use these counters as a threshold 184 // for reliable data. 185 julong _young_gen_change_for_minor_throughput; 186 julong _old_gen_change_for_major_throughput; 187 188 // Accessors 189 190 double gc_pause_goal_sec() const { return _gc_pause_goal_sec; } 191 // The value returned is unitless: it's the proportion of time 192 // spent in a particular collection type. 193 // An interval time will be 0.0 if a collection type hasn't occurred yet. 194 // The 1.4.2 implementation put a floor on the values of major_gc_cost 195 // and minor_gc_cost. This was useful because of the way major_gc_cost 196 // and minor_gc_cost was used in calculating the sizes of the generations. 197 // Do not use a floor in this implementation because any finite value 198 // will put a limit on the throughput that can be achieved and any 199 // throughput goal above that limit will drive the generations sizes 200 // to extremes. 201 double major_gc_cost() const { 202 return MAX2(0.0F, _avg_major_gc_cost->average()); 203 } 204 205 // The value returned is unitless: it's the proportion of time 206 // spent in a particular collection type. 207 // An interval time will be 0.0 if a collection type hasn't occurred yet. 208 // The 1.4.2 implementation put a floor on the values of major_gc_cost 209 // and minor_gc_cost. This was useful because of the way major_gc_cost 210 // and minor_gc_cost was used in calculating the sizes of the generations. 211 // Do not use a floor in this implementation because any finite value 212 // will put a limit on the throughput that can be achieved and any 213 // throughput goal above that limit will drive the generations sizes 214 // to extremes. 215 216 double minor_gc_cost() const { 217 return MAX2(0.0F, _avg_minor_gc_cost->average()); 218 } 219 220 // Because we're dealing with averages, gc_cost() can be 221 // larger than 1.0 if just the sum of the minor cost the 222 // the major cost is used. Worse than that is the 223 // fact that the minor cost and the major cost each 224 // tend toward 1.0 in the extreme of high GC costs. 225 // Limit the value of gc_cost to 1.0 so that the mutator 226 // cost stays non-negative. 227 virtual double gc_cost() const { 228 double result = MIN2(1.0, minor_gc_cost() + major_gc_cost()); 229 assert(result >= 0.0, "Both minor and major costs are non-negative"); 230 return result; 231 } 232 233 // Elapsed time since the last major collection. 234 virtual double time_since_major_gc() const; 235 236 // Average interval between major collections to be used 237 // in calculating the decaying major GC cost. An overestimate 238 // of this time would be a conservative estimate because 239 // this time is used to decide if the major GC cost 240 // should be decayed (i.e., if the time since the last 241 // major GC is long compared to the time returned here, 242 // then the major GC cost will be decayed). See the 243 // implementations for the specifics. 244 virtual double major_gc_interval_average_for_decay() const { 245 return _avg_major_interval->average(); 246 } 247 248 // Return the cost of the GC where the major GC cost 249 // has been decayed based on the time since the last 250 // major collection. 251 double decaying_gc_cost() const; 252 253 // Decay the major GC cost. Use this only for decisions on 254 // whether to adjust, not to determine by how much to adjust. 255 // This approximation is crude and may not be good enough for the 256 // latter. 257 double decaying_major_gc_cost() const; 258 259 // Return the mutator cost using the decayed 260 // GC cost. 261 double adjusted_mutator_cost() const { 262 double result = 1.0 - decaying_gc_cost(); 263 assert(result >= 0.0, "adjusted mutator cost calculation is incorrect"); 264 return result; 265 } 266 267 virtual double mutator_cost() const { 268 double result = 1.0 - gc_cost(); 269 assert(result >= 0.0, "mutator cost calculation is incorrect"); 270 return result; 271 } 272 273 274 bool young_gen_policy_is_ready() { return _young_gen_policy_is_ready; } 275 276 void update_minor_pause_young_estimator(double minor_pause_in_ms); 277 virtual void update_minor_pause_old_estimator(double minor_pause_in_ms) { 278 // This is not meaningful for all policies but needs to be present 279 // to use minor_collection_end() in its current form. 280 } 281 282 virtual size_t eden_increment(size_t cur_eden); 283 virtual size_t eden_increment(size_t cur_eden, uint percent_change); 284 virtual size_t eden_decrement(size_t cur_eden); 285 virtual size_t promo_increment(size_t cur_eden); 286 virtual size_t promo_increment(size_t cur_eden, uint percent_change); 287 virtual size_t promo_decrement(size_t cur_eden); 288 289 virtual void clear_generation_free_space_flags(); 290 291 int change_old_gen_for_throughput() const { 292 return _change_old_gen_for_throughput; 293 } 294 void set_change_old_gen_for_throughput(int v) { 295 _change_old_gen_for_throughput = v; 296 } 297 int change_young_gen_for_throughput() const { 298 return _change_young_gen_for_throughput; 299 } 300 void set_change_young_gen_for_throughput(int v) { 301 _change_young_gen_for_throughput = v; 302 } 303 304 int change_old_gen_for_maj_pauses() const { 305 return _change_old_gen_for_maj_pauses; 306 } 307 void set_change_old_gen_for_maj_pauses(int v) { 308 _change_old_gen_for_maj_pauses = v; 309 } 310 311 bool decrement_tenuring_threshold_for_gc_cost() const { 312 return _decrement_tenuring_threshold_for_gc_cost; 313 } 314 void set_decrement_tenuring_threshold_for_gc_cost(bool v) { 315 _decrement_tenuring_threshold_for_gc_cost = v; 316 } 317 bool increment_tenuring_threshold_for_gc_cost() const { 318 return _increment_tenuring_threshold_for_gc_cost; 319 } 320 void set_increment_tenuring_threshold_for_gc_cost(bool v) { 321 _increment_tenuring_threshold_for_gc_cost = v; 322 } 323 bool decrement_tenuring_threshold_for_survivor_limit() const { 324 return _decrement_tenuring_threshold_for_survivor_limit; 325 } 326 void set_decrement_tenuring_threshold_for_survivor_limit(bool v) { 327 _decrement_tenuring_threshold_for_survivor_limit = v; 328 } 329 // Return true if the policy suggested a change. 330 bool tenuring_threshold_change() const; 331 332 public: 333 AdaptiveSizePolicy(size_t init_eden_size, 334 size_t init_promo_size, 335 size_t init_survivor_size, 336 double gc_pause_goal_sec, 337 uint gc_cost_ratio); 338 339 bool is_gc_cms_adaptive_size_policy() { 340 return kind() == _gc_cms_adaptive_size_policy; 341 } 342 bool is_gc_ps_adaptive_size_policy() { 343 return kind() == _gc_ps_adaptive_size_policy; 344 } 345 346 AdaptivePaddedAverage* avg_minor_pause() const { return _avg_minor_pause; } 347 AdaptiveWeightedAverage* avg_minor_interval() const { 348 return _avg_minor_interval; 349 } 350 AdaptiveWeightedAverage* avg_minor_gc_cost() const { 351 return _avg_minor_gc_cost; 352 } 353 354 AdaptiveWeightedAverage* avg_major_gc_cost() const { 355 return _avg_major_gc_cost; 356 } 357 358 AdaptiveWeightedAverage* avg_young_live() const { return _avg_young_live; } 359 AdaptiveWeightedAverage* avg_eden_live() const { return _avg_eden_live; } 360 AdaptiveWeightedAverage* avg_old_live() const { return _avg_old_live; } 361 362 AdaptivePaddedAverage* avg_survived() const { return _avg_survived; } 363 AdaptivePaddedNoZeroDevAverage* avg_pretenured() { return _avg_pretenured; } 364 365 // Methods indicating events of interest to the adaptive size policy, 366 // called by GC algorithms. It is the responsibility of users of this 367 // policy to call these methods at the correct times! 368 virtual void minor_collection_begin(); 369 virtual void minor_collection_end(GCCause::Cause gc_cause); 370 virtual LinearLeastSquareFit* minor_pause_old_estimator() const { 371 return _minor_pause_old_estimator; 372 } 373 374 LinearLeastSquareFit* minor_pause_young_estimator() { 375 return _minor_pause_young_estimator; 376 } 377 LinearLeastSquareFit* minor_collection_estimator() { 378 return _minor_collection_estimator; 379 } 380 381 LinearLeastSquareFit* major_collection_estimator() { 382 return _major_collection_estimator; 383 } 384 385 float minor_pause_young_slope() { 386 return _minor_pause_young_estimator->slope(); 387 } 388 389 float minor_collection_slope() { return _minor_collection_estimator->slope();} 390 float major_collection_slope() { return _major_collection_estimator->slope();} 391 392 float minor_pause_old_slope() { 393 return _minor_pause_old_estimator->slope(); 394 } 395 396 void set_eden_size(size_t new_size) { 397 _eden_size = new_size; 398 } 399 void set_survivor_size(size_t new_size) { 400 _survivor_size = new_size; 401 } 402 403 size_t calculated_eden_size_in_bytes() const { 404 return _eden_size; 405 } 406 407 size_t calculated_promo_size_in_bytes() const { 408 return _promo_size; 409 } 410 411 size_t calculated_survivor_size_in_bytes() const { 412 return _survivor_size; 413 } 414 415 // This is a hint for the heap: we've detected that gc times 416 // are taking longer than GCTimeLimit allows. 417 // Most heaps will choose to throw an OutOfMemoryError when 418 // this occurs but it is up to the heap to request this information 419 // of the policy 420 bool gc_overhead_limit_exceeded() { 421 return _gc_overhead_limit_exceeded; 422 } 423 void set_gc_overhead_limit_exceeded(bool v) { 424 _gc_overhead_limit_exceeded = v; 425 } 426 427 // Tests conditions indicate the GC overhead limit is being approached. 428 bool gc_overhead_limit_near() { 429 return gc_overhead_limit_count() >= 430 (AdaptiveSizePolicyGCTimeLimitThreshold - 1); 431 } 432 uint gc_overhead_limit_count() { return _gc_overhead_limit_count; } 433 void reset_gc_overhead_limit_count() { _gc_overhead_limit_count = 0; } 434 void inc_gc_overhead_limit_count() { _gc_overhead_limit_count++; } 435 // accessors for flags recording the decisions to resize the 436 // generations to meet the pause goal. 437 438 int change_young_gen_for_min_pauses() const { 439 return _change_young_gen_for_min_pauses; 440 } 441 void set_change_young_gen_for_min_pauses(int v) { 442 _change_young_gen_for_min_pauses = v; 443 } 444 void set_decrease_for_footprint(int v) { _decrease_for_footprint = v; } 445 int decrease_for_footprint() const { return _decrease_for_footprint; } 446 int decide_at_full_gc() { return _decide_at_full_gc; } 447 void set_decide_at_full_gc(int v) { _decide_at_full_gc = v; } 448 449 // Check the conditions for an out-of-memory due to excessive GC time. 450 // Set _gc_overhead_limit_exceeded if all the conditions have been met. 451 void check_gc_overhead_limit(size_t young_live, 452 size_t eden_live, 453 size_t max_old_gen_size, 454 size_t max_eden_size, 455 bool is_full_gc, 456 GCCause::Cause gc_cause, 457 SoftRefPolicy* soft_ref_policy); 458 459 static bool should_update_promo_stats(GCCause::Cause cause) { 460 return ((GCCause::is_user_requested_gc(cause) && 461 UseAdaptiveSizePolicyWithSystemGC) || 462 GCCause::is_tenured_allocation_failure_gc(cause)); 463 } 464 465 static bool should_update_eden_stats(GCCause::Cause cause) { 466 return ((GCCause::is_user_requested_gc(cause) && 467 UseAdaptiveSizePolicyWithSystemGC) || 468 GCCause::is_allocation_failure_gc(cause)); 469 } 470 471 // Printing support 472 virtual bool print() const; 473 void print_tenuring_threshold(uint new_tenuring_threshold) const; 474 }; 475 476 #endif // SHARE_VM_GC_SHARED_ADAPTIVESIZEPOLICY_HPP