Path: blob/master/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
40957 views
/*1* Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_GC_SHARED_ADAPTIVESIZEPOLICY_HPP25#define SHARE_GC_SHARED_ADAPTIVESIZEPOLICY_HPP2627#include "gc/shared/gcCause.hpp"28#include "gc/shared/gcOverheadChecker.hpp"29#include "gc/shared/gcUtil.hpp"30#include "memory/allocation.hpp"3132// This class keeps statistical information and computes the33// size of the heap.3435// Forward decls36class elapsedTimer;3738class AdaptiveSizePolicy : public CHeapObj<mtGC> {39friend class GCAdaptivePolicyCounters;40friend class PSGCAdaptivePolicyCounters;41protected:4243enum GCPolicyKind {44_gc_adaptive_size_policy,45_gc_ps_adaptive_size_policy46};47virtual GCPolicyKind kind() const { return _gc_adaptive_size_policy; }4849enum SizePolicyTrueValues {50decrease_old_gen_for_throughput_true = -7,51decrease_young_gen_for_througput_true = -6,5253increase_old_gen_for_min_pauses_true = -5,54decrease_old_gen_for_min_pauses_true = -4,55decrease_young_gen_for_maj_pauses_true = -3,56increase_young_gen_for_min_pauses_true = -2,57increase_old_gen_for_maj_pauses_true = -1,5859decrease_young_gen_for_min_pauses_true = 1,60decrease_old_gen_for_maj_pauses_true = 2,61increase_young_gen_for_maj_pauses_true = 3,6263increase_old_gen_for_throughput_true = 4,64increase_young_gen_for_througput_true = 5,6566decrease_young_gen_for_footprint_true = 6,67decrease_old_gen_for_footprint_true = 7,68decide_at_full_gc_true = 869};7071// Goal for the fraction of the total time during which application72// threads run73const double _throughput_goal;7475// Last calculated sizes, in bytes, and aligned76size_t _eden_size; // calculated eden free space in bytes77size_t _promo_size; // calculated promoted free space in bytes7879size_t _survivor_size; // calculated survivor size in bytes8081// Support for UseGCOverheadLimit82GCOverheadChecker _overhead_checker;8384// Minor collection timers used to determine both85// pause and interval times for collections86static elapsedTimer _minor_timer;8788// Major collection timers, used to determine both89// pause and interval times for collections90static elapsedTimer _major_timer;9192// Time statistics93AdaptivePaddedAverage* _avg_minor_pause;94AdaptiveWeightedAverage* _avg_minor_interval;95AdaptiveWeightedAverage* _avg_minor_gc_cost;9697AdaptiveWeightedAverage* _avg_major_interval;98AdaptiveWeightedAverage* _avg_major_gc_cost;99100// Footprint statistics101AdaptiveWeightedAverage* _avg_young_live;102AdaptiveWeightedAverage* _avg_eden_live;103AdaptiveWeightedAverage* _avg_old_live;104105// Statistics for survivor space calculation for young generation106AdaptivePaddedAverage* _avg_survived;107108// Objects that have been directly allocated in the old generation109AdaptivePaddedNoZeroDevAverage* _avg_pretenured;110111// Variable for estimating the major and minor pause times.112// These variables represent linear least-squares fits of113// the data.114// minor pause time vs. old gen size115LinearLeastSquareFit* _minor_pause_old_estimator;116// minor pause time vs. young gen size117LinearLeastSquareFit* _minor_pause_young_estimator;118119// Variables for estimating the major and minor collection costs120// minor collection time vs. young gen size121LinearLeastSquareFit* _minor_collection_estimator;122// major collection time vs. old gen size123LinearLeastSquareFit* _major_collection_estimator;124125// These record the most recent collection times. They126// are available as an alternative to using the averages127// for making ergonomic decisions.128double _latest_minor_mutator_interval_seconds;129130// Allowed difference between major and minor GC times, used131// for computing tenuring_threshold132const double _threshold_tolerance_percent;133134const double _gc_pause_goal_sec; // Goal for maximum GC pause135136// Flag indicating that the adaptive policy is ready to use137bool _young_gen_policy_is_ready;138139// Decrease/increase the young generation for minor pause time140int _change_young_gen_for_min_pauses;141142// Decrease/increase the old generation for major pause time143int _change_old_gen_for_maj_pauses;144145// change old generation for throughput146int _change_old_gen_for_throughput;147148// change young generation for throughput149int _change_young_gen_for_throughput;150151// Flag indicating that the policy would152// increase the tenuring threshold because of the total major GC cost153// is greater than the total minor GC cost154bool _increment_tenuring_threshold_for_gc_cost;155// decrease the tenuring threshold because of the the total minor GC156// cost is greater than the total major GC cost157bool _decrement_tenuring_threshold_for_gc_cost;158// decrease due to survivor size limit159bool _decrement_tenuring_threshold_for_survivor_limit;160161// decrease generation sizes for footprint162int _decrease_for_footprint;163164// Set if the ergonomic decisions were made at a full GC.165int _decide_at_full_gc;166167// Changing the generation sizing depends on the data that is168// gathered about the effects of changes on the pause times and169// throughput. These variable count the number of data points170// gathered. The policy may use these counters as a threshold171// for reliable data.172julong _young_gen_change_for_minor_throughput;173julong _old_gen_change_for_major_throughput;174175// Accessors176177double gc_pause_goal_sec() const { return _gc_pause_goal_sec; }178// The value returned is unitless: it's the proportion of time179// spent in a particular collection type.180// An interval time will be 0.0 if a collection type hasn't occurred yet.181// The 1.4.2 implementation put a floor on the values of major_gc_cost182// and minor_gc_cost. This was useful because of the way major_gc_cost183// and minor_gc_cost was used in calculating the sizes of the generations.184// Do not use a floor in this implementation because any finite value185// will put a limit on the throughput that can be achieved and any186// throughput goal above that limit will drive the generations sizes187// to extremes.188double major_gc_cost() const {189return MAX2(0.0F, _avg_major_gc_cost->average());190}191192// The value returned is unitless: it's the proportion of time193// spent in a particular collection type.194// An interval time will be 0.0 if a collection type hasn't occurred yet.195// The 1.4.2 implementation put a floor on the values of major_gc_cost196// and minor_gc_cost. This was useful because of the way major_gc_cost197// and minor_gc_cost was used in calculating the sizes of the generations.198// Do not use a floor in this implementation because any finite value199// will put a limit on the throughput that can be achieved and any200// throughput goal above that limit will drive the generations sizes201// to extremes.202203double minor_gc_cost() const {204return MAX2(0.0F, _avg_minor_gc_cost->average());205}206207// Because we're dealing with averages, gc_cost() can be208// larger than 1.0 if just the sum of the minor cost the209// the major cost is used. Worse than that is the210// fact that the minor cost and the major cost each211// tend toward 1.0 in the extreme of high GC costs.212// Limit the value of gc_cost to 1.0 so that the mutator213// cost stays non-negative.214virtual double gc_cost() const {215double result = MIN2(1.0, minor_gc_cost() + major_gc_cost());216assert(result >= 0.0, "Both minor and major costs are non-negative");217return result;218}219220// Elapsed time since the last major collection.221virtual double time_since_major_gc() const;222223// Average interval between major collections to be used224// in calculating the decaying major GC cost. An overestimate225// of this time would be a conservative estimate because226// this time is used to decide if the major GC cost227// should be decayed (i.e., if the time since the last228// major GC is long compared to the time returned here,229// then the major GC cost will be decayed). See the230// implementations for the specifics.231virtual double major_gc_interval_average_for_decay() const {232return _avg_major_interval->average();233}234235// Return the cost of the GC where the major GC cost236// has been decayed based on the time since the last237// major collection.238double decaying_gc_cost() const;239240// Decay the major GC cost. Use this only for decisions on241// whether to adjust, not to determine by how much to adjust.242// This approximation is crude and may not be good enough for the243// latter.244double decaying_major_gc_cost() const;245246// Return the mutator cost using the decayed247// GC cost.248double adjusted_mutator_cost() const {249double result = 1.0 - decaying_gc_cost();250assert(result >= 0.0, "adjusted mutator cost calculation is incorrect");251return result;252}253254virtual double mutator_cost() const {255double result = 1.0 - gc_cost();256assert(result >= 0.0, "mutator cost calculation is incorrect");257return result;258}259260261bool young_gen_policy_is_ready() { return _young_gen_policy_is_ready; }262263void update_minor_pause_young_estimator(double minor_pause_in_ms);264virtual void update_minor_pause_old_estimator(double minor_pause_in_ms) {265// This is not meaningful for all policies but needs to be present266// to use minor_collection_end() in its current form.267}268269virtual size_t eden_increment(size_t cur_eden);270virtual size_t eden_increment(size_t cur_eden, uint percent_change);271virtual size_t eden_decrement(size_t cur_eden);272virtual size_t promo_increment(size_t cur_eden);273virtual size_t promo_increment(size_t cur_eden, uint percent_change);274virtual size_t promo_decrement(size_t cur_eden);275276virtual void clear_generation_free_space_flags();277278int change_old_gen_for_throughput() const {279return _change_old_gen_for_throughput;280}281void set_change_old_gen_for_throughput(int v) {282_change_old_gen_for_throughput = v;283}284int change_young_gen_for_throughput() const {285return _change_young_gen_for_throughput;286}287void set_change_young_gen_for_throughput(int v) {288_change_young_gen_for_throughput = v;289}290291int change_old_gen_for_maj_pauses() const {292return _change_old_gen_for_maj_pauses;293}294void set_change_old_gen_for_maj_pauses(int v) {295_change_old_gen_for_maj_pauses = v;296}297298bool decrement_tenuring_threshold_for_gc_cost() const {299return _decrement_tenuring_threshold_for_gc_cost;300}301void set_decrement_tenuring_threshold_for_gc_cost(bool v) {302_decrement_tenuring_threshold_for_gc_cost = v;303}304bool increment_tenuring_threshold_for_gc_cost() const {305return _increment_tenuring_threshold_for_gc_cost;306}307void set_increment_tenuring_threshold_for_gc_cost(bool v) {308_increment_tenuring_threshold_for_gc_cost = v;309}310bool decrement_tenuring_threshold_for_survivor_limit() const {311return _decrement_tenuring_threshold_for_survivor_limit;312}313void set_decrement_tenuring_threshold_for_survivor_limit(bool v) {314_decrement_tenuring_threshold_for_survivor_limit = v;315}316// Return true if the policy suggested a change.317bool tenuring_threshold_change() const;318319public:320AdaptiveSizePolicy(size_t init_eden_size,321size_t init_promo_size,322size_t init_survivor_size,323double gc_pause_goal_sec,324uint gc_cost_ratio);325326bool is_gc_ps_adaptive_size_policy() {327return kind() == _gc_ps_adaptive_size_policy;328}329330AdaptivePaddedAverage* avg_minor_pause() const { return _avg_minor_pause; }331AdaptiveWeightedAverage* avg_minor_interval() const {332return _avg_minor_interval;333}334AdaptiveWeightedAverage* avg_minor_gc_cost() const {335return _avg_minor_gc_cost;336}337338AdaptiveWeightedAverage* avg_major_gc_cost() const {339return _avg_major_gc_cost;340}341342AdaptiveWeightedAverage* avg_young_live() const { return _avg_young_live; }343AdaptiveWeightedAverage* avg_eden_live() const { return _avg_eden_live; }344AdaptiveWeightedAverage* avg_old_live() const { return _avg_old_live; }345346AdaptivePaddedAverage* avg_survived() const { return _avg_survived; }347AdaptivePaddedNoZeroDevAverage* avg_pretenured() { return _avg_pretenured; }348349// Methods indicating events of interest to the adaptive size policy,350// called by GC algorithms. It is the responsibility of users of this351// policy to call these methods at the correct times!352virtual void minor_collection_begin();353virtual void minor_collection_end(GCCause::Cause gc_cause);354virtual LinearLeastSquareFit* minor_pause_old_estimator() const {355return _minor_pause_old_estimator;356}357358LinearLeastSquareFit* minor_pause_young_estimator() {359return _minor_pause_young_estimator;360}361LinearLeastSquareFit* minor_collection_estimator() {362return _minor_collection_estimator;363}364365LinearLeastSquareFit* major_collection_estimator() {366return _major_collection_estimator;367}368369float minor_pause_young_slope() {370return _minor_pause_young_estimator->slope();371}372373float minor_collection_slope() { return _minor_collection_estimator->slope();}374float major_collection_slope() { return _major_collection_estimator->slope();}375376float minor_pause_old_slope() {377return _minor_pause_old_estimator->slope();378}379380void set_eden_size(size_t new_size) {381_eden_size = new_size;382}383void set_survivor_size(size_t new_size) {384_survivor_size = new_size;385}386387size_t calculated_eden_size_in_bytes() const {388return _eden_size;389}390391size_t calculated_promo_size_in_bytes() const {392return _promo_size;393}394395size_t calculated_survivor_size_in_bytes() const {396return _survivor_size;397}398399bool gc_overhead_limit_exceeded() {400return _overhead_checker.gc_overhead_limit_exceeded();401}402void set_gc_overhead_limit_exceeded(bool v) {403_overhead_checker.set_gc_overhead_limit_exceeded(v);404}405406bool gc_overhead_limit_near() {407return _overhead_checker.gc_overhead_limit_near();408}409410void reset_gc_overhead_limit_count() {411_overhead_checker.reset_gc_overhead_limit_count();412}413// accessors for flags recording the decisions to resize the414// generations to meet the pause goal.415416int change_young_gen_for_min_pauses() const {417return _change_young_gen_for_min_pauses;418}419void set_change_young_gen_for_min_pauses(int v) {420_change_young_gen_for_min_pauses = v;421}422void set_decrease_for_footprint(int v) { _decrease_for_footprint = v; }423int decrease_for_footprint() const { return _decrease_for_footprint; }424int decide_at_full_gc() { return _decide_at_full_gc; }425void set_decide_at_full_gc(int v) { _decide_at_full_gc = v; }426427// Check the conditions for an out-of-memory due to excessive GC time.428// Set _gc_overhead_limit_exceeded if all the conditions have been met.429void check_gc_overhead_limit(size_t eden_live,430size_t max_old_gen_size,431size_t max_eden_size,432bool is_full_gc,433GCCause::Cause gc_cause,434SoftRefPolicy* soft_ref_policy);435436static bool should_update_promo_stats(GCCause::Cause cause) {437return ((GCCause::is_user_requested_gc(cause) &&438UseAdaptiveSizePolicyWithSystemGC) ||439GCCause::is_tenured_allocation_failure_gc(cause));440}441442static bool should_update_eden_stats(GCCause::Cause cause) {443return ((GCCause::is_user_requested_gc(cause) &&444UseAdaptiveSizePolicyWithSystemGC) ||445GCCause::is_allocation_failure_gc(cause));446}447448// Printing support449virtual bool print() const;450void print_tenuring_threshold(uint new_tenuring_threshold) const;451};452453#endif // SHARE_GC_SHARED_ADAPTIVESIZEPOLICY_HPP454455456