Path: blob/master/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp
41152 views
/*1* Copyright (c) 2002, 2020, 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_PARALLEL_PSADAPTIVESIZEPOLICY_HPP25#define SHARE_GC_PARALLEL_PSADAPTIVESIZEPOLICY_HPP2627#include "gc/shared/adaptiveSizePolicy.hpp"28#include "gc/shared/gcCause.hpp"29#include "gc/shared/gcStats.hpp"30#include "gc/shared/gcUtil.hpp"31#include "utilities/align.hpp"3233// This class keeps statistical information and computes the34// optimal free space for both the young and old generation35// based on current application characteristics (based on gc cost36// and application footprint).37//38// It also computes an optimal tenuring threshold between the young39// and old generations, so as to equalize the cost of collections40// of those generations, as well as optimal survivor space sizes41// for the young generation.42//43// While this class is specifically intended for a generational system44// consisting of a young gen (containing an Eden and two semi-spaces)45// and a tenured gen, as well as a perm gen for reflective data, it46// makes NO references to specific generations.47//48// 05/02/2003 Update49// The 1.5 policy makes use of data gathered for the costs of GC on50// specific generations. That data does reference specific51// generation. Also diagnostics specific to generations have52// been added.5354// Forward decls55class elapsedTimer;5657class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {58friend class PSGCAdaptivePolicyCounters;59private:60// These values are used to record decisions made during the61// policy. For example, if the young generation was decreased62// to decrease the GC cost of minor collections the value63// decrease_young_gen_for_throughput_true is used.6465// Last calculated sizes, in bytes, and aligned66// NEEDS_CLEANUP should use sizes.hpp, but it works in ints, not size_t's6768// Time statistics69AdaptivePaddedAverage* _avg_major_pause;7071// Footprint statistics72AdaptiveWeightedAverage* _avg_base_footprint;7374// Statistical data gathered for GC75GCStats _gc_stats;7677const double _collection_cost_margin_fraction;7879// Variable for estimating the major and minor pause times.80// These variables represent linear least-squares fits of81// the data.82// major pause time vs. old gen size83LinearLeastSquareFit* _major_pause_old_estimator;84// major pause time vs. young gen size85LinearLeastSquareFit* _major_pause_young_estimator;868788// These record the most recent collection times. They89// are available as an alternative to using the averages90// for making ergonomic decisions.91double _latest_major_mutator_interval_seconds;9293const size_t _space_alignment; // alignment for eden, survivors9495const double _gc_minor_pause_goal_sec; // goal for maximum minor gc pause9697// The amount of live data in the heap at the last full GC, used98// as a baseline to help us determine when we need to perform the99// next full GC.100size_t _live_at_last_full_gc;101102// decrease/increase the old generation for minor pause time103int _change_old_gen_for_min_pauses;104105// increase/decrease the young generation for major pause time106int _change_young_gen_for_maj_pauses;107108// To facilitate faster growth at start up, supplement the normal109// growth percentage for the young gen eden and the110// old gen space for promotion with these value which decay111// with increasing collections.112uint _young_gen_size_increment_supplement;113uint _old_gen_size_increment_supplement;114115private:116117// Accessors118AdaptivePaddedAverage* avg_major_pause() const { return _avg_major_pause; }119double gc_minor_pause_goal_sec() const { return _gc_minor_pause_goal_sec; }120121void adjust_eden_for_minor_pause_time(bool is_full_gc,122size_t* desired_eden_size_ptr);123// Change the generation sizes to achieve a GC pause time goal124// Returned sizes are not necessarily aligned.125void adjust_promo_for_pause_time(bool is_full_gc,126size_t* desired_promo_size_ptr,127size_t* desired_eden_size_ptr);128void adjust_eden_for_pause_time(bool is_full_gc,129size_t* desired_promo_size_ptr,130size_t* desired_eden_size_ptr);131// Change the generation sizes to achieve an application throughput goal132// Returned sizes are not necessarily aligned.133void adjust_promo_for_throughput(bool is_full_gc,134size_t* desired_promo_size_ptr);135void adjust_eden_for_throughput(bool is_full_gc,136size_t* desired_eden_size_ptr);137// Change the generation sizes to achieve minimum footprint138// Returned sizes are not aligned.139size_t adjust_promo_for_footprint(size_t desired_promo_size,140size_t desired_total);141size_t adjust_eden_for_footprint(size_t desired_promo_size,142size_t desired_total);143144// Size in bytes for an increment or decrement of eden.145virtual size_t eden_increment(size_t cur_eden, uint percent_change);146virtual size_t eden_decrement(size_t cur_eden);147size_t eden_decrement_aligned_down(size_t cur_eden);148size_t eden_increment_with_supplement_aligned_up(size_t cur_eden);149150// Size in bytes for an increment or decrement of the promotion area151virtual size_t promo_increment(size_t cur_promo, uint percent_change);152virtual size_t promo_decrement(size_t cur_promo);153size_t promo_decrement_aligned_down(size_t cur_promo);154size_t promo_increment_with_supplement_aligned_up(size_t cur_promo);155156// Returns a change that has been scaled down. Result157// is not aligned. (If useful, move to some shared158// location.)159size_t scale_down(size_t change, double part, double total);160161protected:162// Time accessors163164// Footprint accessors165size_t live_space() const {166return (size_t)(avg_base_footprint()->average() +167avg_young_live()->average() +168avg_old_live()->average());169}170size_t free_space() const {171return _eden_size + _promo_size;172}173174void set_promo_size(size_t new_size) {175_promo_size = new_size;176}177void set_survivor_size(size_t new_size) {178_survivor_size = new_size;179}180181// Update estimators182void update_minor_pause_old_estimator(double minor_pause_in_ms);183184virtual GCPolicyKind kind() const { return _gc_ps_adaptive_size_policy; }185186public:187virtual size_t eden_increment(size_t cur_eden);188virtual size_t promo_increment(size_t cur_promo);189190// Accessors for use by performance counters191AdaptivePaddedNoZeroDevAverage* avg_promoted() const {192return _gc_stats.avg_promoted();193}194AdaptiveWeightedAverage* avg_base_footprint() const {195return _avg_base_footprint;196}197198// Input arguments are initial free space sizes for young and old199// generations, the initial survivor space size, the200// alignment values and the pause & throughput goals.201//202// NEEDS_CLEANUP this is a singleton object203PSAdaptiveSizePolicy(size_t init_eden_size,204size_t init_promo_size,205size_t init_survivor_size,206size_t space_alignment,207double gc_pause_goal_sec,208double gc_minor_pause_goal_sec,209uint gc_time_ratio);210211// Methods indicating events of interest to the adaptive size policy,212// called by GC algorithms. It is the responsibility of users of this213// policy to call these methods at the correct times!214void major_collection_begin();215void major_collection_end(size_t amount_live, GCCause::Cause gc_cause);216217void tenured_allocation(size_t size) {218_avg_pretenured->sample(size);219}220221// Accessors222// NEEDS_CLEANUP should use sizes.hpp223224static size_t calculate_free_based_on_live(size_t live, uintx ratio_as_percentage);225226size_t calculated_old_free_size_in_bytes() const;227228size_t average_old_live_in_bytes() const {229return (size_t) avg_old_live()->average();230}231232size_t average_promoted_in_bytes() const {233return (size_t)avg_promoted()->average();234}235236size_t padded_average_promoted_in_bytes() const {237return (size_t)avg_promoted()->padded_average();238}239240int change_young_gen_for_maj_pauses() {241return _change_young_gen_for_maj_pauses;242}243void set_change_young_gen_for_maj_pauses(int v) {244_change_young_gen_for_maj_pauses = v;245}246247int change_old_gen_for_min_pauses() {248return _change_old_gen_for_min_pauses;249}250void set_change_old_gen_for_min_pauses(int v) {251_change_old_gen_for_min_pauses = v;252}253254// Return true if the old generation size was changed255// to try to reach a pause time goal.256bool old_gen_changed_for_pauses() {257bool result = _change_old_gen_for_maj_pauses != 0 ||258_change_old_gen_for_min_pauses != 0;259return result;260}261262// Return true if the young generation size was changed263// to try to reach a pause time goal.264bool young_gen_changed_for_pauses() {265bool result = _change_young_gen_for_min_pauses != 0 ||266_change_young_gen_for_maj_pauses != 0;267return result;268}269// end flags for pause goal270271// Return true if the old generation size was changed272// to try to reach a throughput goal.273bool old_gen_changed_for_throughput() {274bool result = _change_old_gen_for_throughput != 0;275return result;276}277278// Return true if the young generation size was changed279// to try to reach a throughput goal.280bool young_gen_changed_for_throughput() {281bool result = _change_young_gen_for_throughput != 0;282return result;283}284285int decrease_for_footprint() { return _decrease_for_footprint; }286287288// Accessors for estimators. The slope of the linear fit is289// currently all that is used for making decisions.290291LinearLeastSquareFit* major_pause_old_estimator() {292return _major_pause_old_estimator;293}294295LinearLeastSquareFit* major_pause_young_estimator() {296return _major_pause_young_estimator;297}298299300virtual void clear_generation_free_space_flags();301302float major_pause_old_slope() { return _major_pause_old_estimator->slope(); }303float major_pause_young_slope() {304return _major_pause_young_estimator->slope();305}306float major_collection_slope() { return _major_collection_estimator->slope();}307308// Given the amount of live data in the heap, should we309// perform a Full GC?310bool should_full_GC(size_t live_in_old_gen);311312// Calculates optimal (free) space sizes for both the young and old313// generations. Stores results in _eden_size and _promo_size.314// Takes current used space in all generations as input, as well315// as an indication if a full gc has just been performed, for use316// in deciding if an OOM error should be thrown.317void compute_generations_free_space(size_t young_live,318size_t eden_live,319size_t old_live,320size_t cur_eden, // current eden in bytes321size_t max_old_gen_size,322size_t max_eden_size,323bool is_full_gc);324325void compute_eden_space_size(size_t young_live,326size_t eden_live,327size_t cur_eden, // current eden in bytes328size_t max_eden_size,329bool is_full_gc);330331void compute_old_gen_free_space(size_t old_live,332size_t cur_eden, // current eden in bytes333size_t max_old_gen_size,334bool is_full_gc);335336// Calculates new survivor space size; returns a new tenuring threshold337// value. Stores new survivor size in _survivor_size.338uint compute_survivor_space_size_and_threshold(bool is_survivor_overflow,339uint tenuring_threshold,340size_t survivor_limit);341342// Return the maximum size of a survivor space if the young generation were of343// size gen_size.344size_t max_survivor_size(size_t gen_size) {345// Never allow the target survivor size to grow more than MinSurvivorRatio346// of the young generation size. We cannot grow into a two semi-space347// system, with Eden zero sized. Even if the survivor space grows, from()348// might grow by moving the bottom boundary "down" -- so from space will349// remain almost full anyway (top() will be near end(), but there will be a350// large filler object at the bottom).351const size_t sz = gen_size / MinSurvivorRatio;352const size_t alignment = _space_alignment;353return sz > alignment ? align_down(sz, alignment) : alignment;354}355356size_t live_at_last_full_gc() {357return _live_at_last_full_gc;358}359360// Update averages that are always used (even361// if adaptive sizing is turned off).362void update_averages(bool is_survivor_overflow,363size_t survived,364size_t promoted);365366// Printing support367virtual bool print() const;368369// Decay the supplemental growth additive.370void decay_supplemental_growth(bool is_full_gc);371};372373#endif // SHARE_GC_PARALLEL_PSADAPTIVESIZEPOLICY_HPP374375376