/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "gc_implementation/shared/gcUtil.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "gc_interface/gcCause.hpp"
#include "memory/allocation.hpp"
#include "memory/universe.hpp"
// This class keeps statistical information and computes the
// size of the heap.
// Forward decls
class elapsedTimer;
class CollectorPolicy;
friend class GCAdaptivePolicyCounters;
friend class PSGCAdaptivePolicyCounters;
friend class CMSGCAdaptivePolicyCounters;
protected:
enum GCPolicyKind {
};
enum SizePolicyTrueValues {
};
// Goal for the fraction of the total time during which application
// threads run.
const double _throughput_goal;
// Last calculated sizes, in bytes, and aligned
// This is a hint for the heap: we've detected that gc times
// are taking longer than GCTimeLimit allows.
// Use for diagnostics only. If UseGCOverheadLimit is false,
// this variable is still set.
// Count of consecutive GC that have exceeded the
// GC time limit criterion.
// This flag signals that GCTimeLimit is being exceeded
// but may not have done so for the required number of consequetive
// collections.
// Minor collection timers used to determine both
// pause and interval times for collections.
// Major collection timers, used to determine both
// pause and interval times for collections
// Time statistics
// Footprint statistics
// Statistics for survivor space calculation for young generation
// Objects that have been directly allocated in the old generation.
// Variable for estimating the major and minor pause times.
// These variables represent linear least-squares fits of
// the data.
// minor pause time vs. old gen size
// minor pause time vs. young gen size
// Variables for estimating the major and minor collection costs
// minor collection time vs. young gen size
// major collection time vs. cms gen size
// These record the most recent collection times. They
// are available as an alternative to using the averages
// for making ergonomic decisions.
// Allowed difference between major and minor gc times, used
// for computing tenuring_threshold.
const double _threshold_tolerance_percent;
// Flag indicating that the adaptive policy is ready to use
// change old geneneration for throughput
// change young generation for throughput
// Flag indicating that the policy would
// increase the tenuring threshold because of the total major gc cost
// is greater than the total minor gc cost
// decrease the tenuring threshold because of the the total minor gc
// cost is greater than the total major gc cost
// decrease due to survivor size limit
// decrease generation sizes for footprint
// Set if the ergonomic decisions were made at a full GC.
int _decide_at_full_gc;
// Changing the generation sizing depends on the data that is
// gathered about the effects of changes on the pause times and
// throughput. These variable count the number of data points
// gathered. The policy may use these counters as a threshhold
// for reliable data.
// Accessors
// The value returned is unitless: it's the proportion of time
// spent in a particular collection type.
// An interval time will be 0.0 if a collection type hasn't occurred yet.
// The 1.4.2 implementation put a floor on the values of major_gc_cost
// and minor_gc_cost. This was useful because of the way major_gc_cost
// and minor_gc_cost was used in calculating the sizes of the generations.
// Do not use a floor in this implementation because any finite value
// will put a limit on the throughput that can be achieved and any
// throughput goal above that limit will drive the generations sizes
// to extremes.
double major_gc_cost() const {
}
// The value returned is unitless: it's the proportion of time
// spent in a particular collection type.
// An interval time will be 0.0 if a collection type hasn't occurred yet.
// The 1.4.2 implementation put a floor on the values of major_gc_cost
// and minor_gc_cost. This was useful because of the way major_gc_cost
// and minor_gc_cost was used in calculating the sizes of the generations.
// Do not use a floor in this implementation because any finite value
// will put a limit on the throughput that can be achieved and any
// throughput goal above that limit will drive the generations sizes
// to extremes.
double minor_gc_cost() const {
}
// Because we're dealing with averages, gc_cost() can be
// larger than 1.0 if just the sum of the minor cost the
// the major cost is used. Worse than that is the
// fact that the minor cost and the major cost each
// tend toward 1.0 in the extreme of high gc costs.
// Limit the value of gc_cost to 1.0 so that the mutator
// cost stays non-negative.
virtual double gc_cost() const {
return result;
}
// Elapsed time since the last major collection.
virtual double time_since_major_gc() const;
// Average interval between major collections to be used
// in calculating the decaying major gc cost. An overestimate
// of this time would be a conservative estimate because
// this time is used to decide if the major GC cost
// should be decayed (i.e., if the time since the last
// major gc is long compared to the time returned here,
// then the major GC cost will be decayed). See the
// implementations for the specifics.
virtual double major_gc_interval_average_for_decay() const {
return _avg_major_interval->average();
}
// Return the cost of the GC where the major gc cost
// has been decayed based on the time since the last
// major collection.
double decaying_gc_cost() const;
// Decay the major gc cost. Use this only for decisions on
// whether to adjust, not to determine by how much to adjust.
// This approximation is crude and may not be good enough for the
// latter.
double decaying_major_gc_cost() const;
// Return the mutator cost using the decayed
// GC cost.
double adjusted_mutator_cost() const {
return result;
}
virtual double mutator_cost() const {
return result;
}
void update_minor_pause_young_estimator(double minor_pause_in_ms);
// This is not meaningful for all policies but needs to be present
// to use minor_collection_end() in its current form.
}
virtual void clear_generation_free_space_flags();
int change_old_gen_for_throughput() const {
return _change_old_gen_for_throughput;
}
void set_change_old_gen_for_throughput(int v) {
}
int change_young_gen_for_throughput() const {
return _change_young_gen_for_throughput;
}
void set_change_young_gen_for_throughput(int v) {
}
int change_old_gen_for_maj_pauses() const {
return _change_old_gen_for_maj_pauses;
}
void set_change_old_gen_for_maj_pauses(int v) {
}
bool decrement_tenuring_threshold_for_gc_cost() const {
}
void set_decrement_tenuring_threshold_for_gc_cost(bool v) {
}
bool increment_tenuring_threshold_for_gc_cost() const {
}
void set_increment_tenuring_threshold_for_gc_cost(bool v) {
}
bool decrement_tenuring_threshold_for_survivor_limit() const {
}
void set_decrement_tenuring_threshold_for_survivor_limit(bool v) {
}
// Return true if the policy suggested a change.
bool tenuring_threshold_change() const;
static bool _debug_perturbation;
public:
double gc_pause_goal_sec,
// Return number default GC threads to use in the next GC.
const uintx min_workers,
// Return number of GC threads to use in the next GC.
// This is called sparingly so as not to change the
// number of GC workers gratuitously.
// For ParNew collections
// For PS scavenge and ParOld collections
// For G1 evacuation pauses (subject to update)
// Other collection phases inherit the number of
// GC workers from the calls above. For example,
// a CMS parallel remark uses the same number of GC
// workers as the most recent ParNew collection.
// Return number of GC threads to use in the next concurrent GC phase.
bool is_gc_cms_adaptive_size_policy() {
return kind() == _gc_cms_adaptive_size_policy;
}
bool is_gc_ps_adaptive_size_policy() {
return kind() == _gc_ps_adaptive_size_policy;
}
return _avg_minor_interval;
}
return _avg_minor_gc_cost;
}
return _avg_major_gc_cost;
}
// Methods indicating events of interest to the adaptive size policy,
// called by GC algorithms. It is the responsibility of users of this
// policy to call these methods at the correct times!
virtual void minor_collection_begin();
return _minor_pause_old_estimator;
}
return _minor_pause_young_estimator;
}
return _minor_collection_estimator;
}
return _major_collection_estimator;
}
float minor_pause_young_slope() {
return _minor_pause_young_estimator->slope();
}
float minor_pause_old_slope() {
return _minor_pause_old_estimator->slope();
}
}
}
return _eden_size;
}
return _promo_size;
}
return _survivor_size;
}
// This is a hint for the heap: we've detected that gc times
// are taking longer than GCTimeLimit allows.
// Most heaps will choose to throw an OutOfMemoryError when
// this occurs but it is up to the heap to request this information
// of the policy
bool gc_overhead_limit_exceeded() {
return _gc_overhead_limit_exceeded;
}
void set_gc_overhead_limit_exceeded(bool v) {
}
// Tests conditions indicate the GC overhead limit is being approached.
bool gc_overhead_limit_near() {
return gc_overhead_limit_count() >=
}
// accessors for flags recording the decisions to resize the
// generations to meet the pause goal.
int change_young_gen_for_min_pauses() const {
return _change_young_gen_for_min_pauses;
}
void set_change_young_gen_for_min_pauses(int v) {
}
// Check the conditions for an out-of-memory due to excessive GC time.
// Set _gc_overhead_limit_exceeded if all the conditions have been met.
bool is_full_gc,
// Printing support
tenuring_threshold) const;
};
// Class that can be used to print information about the
// adaptive size policy at intervals specified by
// AdaptiveSizePolicyOutputInterval. Only print information
// if an adaptive size policy is in use.
bool _do_print;
// A count of zero is a special value that indicates that the
// interval test should be ignored. An interval is of zero is
// a special value that indicates that the interval test should
// always fail (never do the print based on the interval test).
return PrintGCDetails &&
(UseParallelGC || UseConcMarkSweepGC) &&
(AdaptiveSizePolicyOutputInterval > 0) &&
((count == 0) ||
((count % AdaptiveSizePolicyOutputInterval) == 0));
}
public:
// The special value of a zero count can be used to ignore
// the count test.
if (UseAdaptiveSizePolicy && (AdaptiveSizePolicyOutputInterval > 0)) {
} else {
_size_policy = NULL;
_do_print = false;
}
}
if (UseAdaptiveSizePolicy && (AdaptiveSizePolicyOutputInterval > 0)) {
} else {
_do_print = false;
}
}
if (_do_print) {
}
}
};
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_ADAPTIVESIZEPOLICY_HPP