src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp

Thu, 22 Sep 2011 10:57:37 -0700

author
johnc
date
Thu, 22 Sep 2011 10:57:37 -0700
changeset 3175
4dfb2df418f2
parent 2314
f95d63e2154a
child 4037
da91efe96a93
permissions
-rw-r--r--

6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp

duke@435 1 /*
trims@1907 2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSADAPTIVESIZEPOLICY_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSADAPTIVESIZEPOLICY_HPP
stefank@2314 27
stefank@2314 28 #include "gc_implementation/shared/adaptiveSizePolicy.hpp"
stefank@2314 29 #include "gc_implementation/shared/gcStats.hpp"
stefank@2314 30 #include "gc_implementation/shared/gcUtil.hpp"
stefank@2314 31 #include "gc_interface/gcCause.hpp"
stefank@2314 32
duke@435 33 // This class keeps statistical information and computes the
duke@435 34 // optimal free space for both the young and old generation
duke@435 35 // based on current application characteristics (based on gc cost
duke@435 36 // and application footprint).
duke@435 37 //
duke@435 38 // It also computes an optimal tenuring threshold between the young
duke@435 39 // and old generations, so as to equalize the cost of collections
duke@435 40 // of those generations, as well as optimial survivor space sizes
duke@435 41 // for the young generation.
duke@435 42 //
duke@435 43 // While this class is specifically intended for a generational system
duke@435 44 // consisting of a young gen (containing an Eden and two semi-spaces)
duke@435 45 // and a tenured gen, as well as a perm gen for reflective data, it
duke@435 46 // makes NO references to specific generations.
duke@435 47 //
duke@435 48 // 05/02/2003 Update
duke@435 49 // The 1.5 policy makes use of data gathered for the costs of GC on
duke@435 50 // specific generations. That data does reference specific
duke@435 51 // generation. Also diagnostics specific to generations have
duke@435 52 // been added.
duke@435 53
duke@435 54 // Forward decls
duke@435 55 class elapsedTimer;
jmasa@1822 56 class GenerationSizer;
duke@435 57
duke@435 58 class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
duke@435 59 friend class PSGCAdaptivePolicyCounters;
duke@435 60 private:
duke@435 61 // These values are used to record decisions made during the
duke@435 62 // policy. For example, if the young generation was decreased
duke@435 63 // to decrease the GC cost of minor collections the value
duke@435 64 // decrease_young_gen_for_throughput_true is used.
duke@435 65
duke@435 66 // Last calculated sizes, in bytes, and aligned
duke@435 67 // NEEDS_CLEANUP should use sizes.hpp, but it works in ints, not size_t's
duke@435 68
duke@435 69 // Time statistics
duke@435 70 AdaptivePaddedAverage* _avg_major_pause;
duke@435 71
duke@435 72 // Footprint statistics
duke@435 73 AdaptiveWeightedAverage* _avg_base_footprint;
duke@435 74
duke@435 75 // Statistical data gathered for GC
duke@435 76 GCStats _gc_stats;
duke@435 77
duke@435 78 size_t _survivor_size_limit; // Limit in bytes of survivor size
duke@435 79 const double _collection_cost_margin_fraction;
duke@435 80
duke@435 81 // Variable for estimating the major and minor pause times.
duke@435 82 // These variables represent linear least-squares fits of
duke@435 83 // the data.
duke@435 84 // major pause time vs. old gen size
duke@435 85 LinearLeastSquareFit* _major_pause_old_estimator;
duke@435 86 // major pause time vs. young gen size
duke@435 87 LinearLeastSquareFit* _major_pause_young_estimator;
duke@435 88
duke@435 89
duke@435 90 // These record the most recent collection times. They
duke@435 91 // are available as an alternative to using the averages
duke@435 92 // for making ergonomic decisions.
duke@435 93 double _latest_major_mutator_interval_seconds;
duke@435 94
duke@435 95 const size_t _intra_generation_alignment; // alignment for eden, survivors
duke@435 96
duke@435 97 const double _gc_minor_pause_goal_sec; // goal for maximum minor gc pause
duke@435 98
duke@435 99 // The amount of live data in the heap at the last full GC, used
duke@435 100 // as a baseline to help us determine when we need to perform the
duke@435 101 // next full GC.
duke@435 102 size_t _live_at_last_full_gc;
duke@435 103
duke@435 104 // decrease/increase the old generation for minor pause time
duke@435 105 int _change_old_gen_for_min_pauses;
duke@435 106
duke@435 107 // increase/decrease the young generation for major pause time
duke@435 108 int _change_young_gen_for_maj_pauses;
duke@435 109
duke@435 110
duke@435 111 // Flag indicating that the adaptive policy is ready to use
duke@435 112 bool _old_gen_policy_is_ready;
duke@435 113
duke@435 114 // Changing the generation sizing depends on the data that is
duke@435 115 // gathered about the effects of changes on the pause times and
duke@435 116 // throughput. These variable count the number of data points
duke@435 117 // gathered. The policy may use these counters as a threshhold
duke@435 118 // for reliable data.
duke@435 119 julong _young_gen_change_for_major_pause_count;
duke@435 120
duke@435 121 // To facilitate faster growth at start up, supplement the normal
duke@435 122 // growth percentage for the young gen eden and the
duke@435 123 // old gen space for promotion with these value which decay
duke@435 124 // with increasing collections.
duke@435 125 uint _young_gen_size_increment_supplement;
duke@435 126 uint _old_gen_size_increment_supplement;
duke@435 127
duke@435 128 // The number of bytes absorbed from eden into the old gen by moving the
duke@435 129 // boundary over live data.
duke@435 130 size_t _bytes_absorbed_from_eden;
duke@435 131
duke@435 132 private:
duke@435 133
duke@435 134 // Accessors
duke@435 135 AdaptivePaddedAverage* avg_major_pause() const { return _avg_major_pause; }
duke@435 136 double gc_minor_pause_goal_sec() const { return _gc_minor_pause_goal_sec; }
duke@435 137
duke@435 138 // Change the young generation size to achieve a minor GC pause time goal
duke@435 139 void adjust_for_minor_pause_time(bool is_full_gc,
duke@435 140 size_t* desired_promo_size_ptr,
duke@435 141 size_t* desired_eden_size_ptr);
duke@435 142 // Change the generation sizes to achieve a GC pause time goal
duke@435 143 // Returned sizes are not necessarily aligned.
duke@435 144 void adjust_for_pause_time(bool is_full_gc,
duke@435 145 size_t* desired_promo_size_ptr,
duke@435 146 size_t* desired_eden_size_ptr);
duke@435 147 // Change the generation sizes to achieve an application throughput goal
duke@435 148 // Returned sizes are not necessarily aligned.
duke@435 149 void adjust_for_throughput(bool is_full_gc,
duke@435 150 size_t* desired_promo_size_ptr,
duke@435 151 size_t* desired_eden_size_ptr);
duke@435 152 // Change the generation sizes to achieve minimum footprint
duke@435 153 // Returned sizes are not aligned.
duke@435 154 size_t adjust_promo_for_footprint(size_t desired_promo_size,
duke@435 155 size_t desired_total);
duke@435 156 size_t adjust_eden_for_footprint(size_t desired_promo_size,
duke@435 157 size_t desired_total);
duke@435 158
duke@435 159 // Size in bytes for an increment or decrement of eden.
duke@435 160 virtual size_t eden_increment(size_t cur_eden, uint percent_change);
duke@435 161 virtual size_t eden_decrement(size_t cur_eden);
duke@435 162 size_t eden_decrement_aligned_down(size_t cur_eden);
duke@435 163 size_t eden_increment_with_supplement_aligned_up(size_t cur_eden);
duke@435 164
duke@435 165 // Size in bytes for an increment or decrement of the promotion area
duke@435 166 virtual size_t promo_increment(size_t cur_promo, uint percent_change);
duke@435 167 virtual size_t promo_decrement(size_t cur_promo);
duke@435 168 size_t promo_decrement_aligned_down(size_t cur_promo);
duke@435 169 size_t promo_increment_with_supplement_aligned_up(size_t cur_promo);
duke@435 170
duke@435 171 // Decay the supplemental growth additive.
duke@435 172 void decay_supplemental_growth(bool is_full_gc);
duke@435 173
duke@435 174 // Returns a change that has been scaled down. Result
duke@435 175 // is not aligned. (If useful, move to some shared
duke@435 176 // location.)
duke@435 177 size_t scale_down(size_t change, double part, double total);
duke@435 178
duke@435 179 protected:
duke@435 180 // Time accessors
duke@435 181
duke@435 182 // Footprint accessors
duke@435 183 size_t live_space() const {
duke@435 184 return (size_t)(avg_base_footprint()->average() +
duke@435 185 avg_young_live()->average() +
duke@435 186 avg_old_live()->average());
duke@435 187 }
duke@435 188 size_t free_space() const {
duke@435 189 return _eden_size + _promo_size;
duke@435 190 }
duke@435 191
duke@435 192 void set_promo_size(size_t new_size) {
duke@435 193 _promo_size = new_size;
duke@435 194 }
duke@435 195 void set_survivor_size(size_t new_size) {
duke@435 196 _survivor_size = new_size;
duke@435 197 }
duke@435 198
duke@435 199 // Update estimators
duke@435 200 void update_minor_pause_old_estimator(double minor_pause_in_ms);
duke@435 201
duke@435 202 virtual GCPolicyKind kind() const { return _gc_ps_adaptive_size_policy; }
duke@435 203
duke@435 204 public:
duke@435 205 // Use by ASPSYoungGen and ASPSOldGen to limit boundary moving.
duke@435 206 size_t eden_increment_aligned_up(size_t cur_eden);
duke@435 207 size_t eden_increment_aligned_down(size_t cur_eden);
duke@435 208 size_t promo_increment_aligned_up(size_t cur_promo);
duke@435 209 size_t promo_increment_aligned_down(size_t cur_promo);
duke@435 210
duke@435 211 virtual size_t eden_increment(size_t cur_eden);
duke@435 212 virtual size_t promo_increment(size_t cur_promo);
duke@435 213
duke@435 214 // Accessors for use by performance counters
duke@435 215 AdaptivePaddedNoZeroDevAverage* avg_promoted() const {
duke@435 216 return _gc_stats.avg_promoted();
duke@435 217 }
duke@435 218 AdaptiveWeightedAverage* avg_base_footprint() const {
duke@435 219 return _avg_base_footprint;
duke@435 220 }
duke@435 221
duke@435 222 // Input arguments are initial free space sizes for young and old
duke@435 223 // generations, the initial survivor space size, the
duke@435 224 // alignment values and the pause & throughput goals.
duke@435 225 //
duke@435 226 // NEEDS_CLEANUP this is a singleton object
duke@435 227 PSAdaptiveSizePolicy(size_t init_eden_size,
duke@435 228 size_t init_promo_size,
duke@435 229 size_t init_survivor_size,
duke@435 230 size_t intra_generation_alignment,
duke@435 231 double gc_pause_goal_sec,
duke@435 232 double gc_minor_pause_goal_sec,
duke@435 233 uint gc_time_ratio);
duke@435 234
duke@435 235 // Methods indicating events of interest to the adaptive size policy,
duke@435 236 // called by GC algorithms. It is the responsibility of users of this
duke@435 237 // policy to call these methods at the correct times!
duke@435 238 void major_collection_begin();
duke@435 239 void major_collection_end(size_t amount_live, GCCause::Cause gc_cause);
duke@435 240
duke@435 241 //
duke@435 242 void tenured_allocation(size_t size) {
duke@435 243 _avg_pretenured->sample(size);
duke@435 244 }
duke@435 245
duke@435 246 // Accessors
duke@435 247 // NEEDS_CLEANUP should use sizes.hpp
duke@435 248
duke@435 249 size_t calculated_old_free_size_in_bytes() const {
duke@435 250 return (size_t)(_promo_size + avg_promoted()->padded_average());
duke@435 251 }
duke@435 252
duke@435 253 size_t average_old_live_in_bytes() const {
duke@435 254 return (size_t) avg_old_live()->average();
duke@435 255 }
duke@435 256
duke@435 257 size_t average_promoted_in_bytes() const {
duke@435 258 return (size_t)avg_promoted()->average();
duke@435 259 }
duke@435 260
duke@435 261 size_t padded_average_promoted_in_bytes() const {
duke@435 262 return (size_t)avg_promoted()->padded_average();
duke@435 263 }
duke@435 264
duke@435 265 int change_young_gen_for_maj_pauses() {
duke@435 266 return _change_young_gen_for_maj_pauses;
duke@435 267 }
duke@435 268 void set_change_young_gen_for_maj_pauses(int v) {
duke@435 269 _change_young_gen_for_maj_pauses = v;
duke@435 270 }
duke@435 271
duke@435 272 int change_old_gen_for_min_pauses() {
duke@435 273 return _change_old_gen_for_min_pauses;
duke@435 274 }
duke@435 275 void set_change_old_gen_for_min_pauses(int v) {
duke@435 276 _change_old_gen_for_min_pauses = v;
duke@435 277 }
duke@435 278
duke@435 279 // Return true if the old generation size was changed
duke@435 280 // to try to reach a pause time goal.
duke@435 281 bool old_gen_changed_for_pauses() {
duke@435 282 bool result = _change_old_gen_for_maj_pauses != 0 ||
duke@435 283 _change_old_gen_for_min_pauses != 0;
duke@435 284 return result;
duke@435 285 }
duke@435 286
duke@435 287 // Return true if the young generation size was changed
duke@435 288 // to try to reach a pause time goal.
duke@435 289 bool young_gen_changed_for_pauses() {
duke@435 290 bool result = _change_young_gen_for_min_pauses != 0 ||
duke@435 291 _change_young_gen_for_maj_pauses != 0;
duke@435 292 return result;
duke@435 293 }
duke@435 294 // end flags for pause goal
duke@435 295
duke@435 296 // Return true if the old generation size was changed
duke@435 297 // to try to reach a throughput goal.
duke@435 298 bool old_gen_changed_for_throughput() {
duke@435 299 bool result = _change_old_gen_for_throughput != 0;
duke@435 300 return result;
duke@435 301 }
duke@435 302
duke@435 303 // Return true if the young generation size was changed
duke@435 304 // to try to reach a throughput goal.
duke@435 305 bool young_gen_changed_for_throughput() {
duke@435 306 bool result = _change_young_gen_for_throughput != 0;
duke@435 307 return result;
duke@435 308 }
duke@435 309
duke@435 310 int decrease_for_footprint() { return _decrease_for_footprint; }
duke@435 311
duke@435 312
duke@435 313 // Accessors for estimators. The slope of the linear fit is
duke@435 314 // currently all that is used for making decisions.
duke@435 315
duke@435 316 LinearLeastSquareFit* major_pause_old_estimator() {
duke@435 317 return _major_pause_old_estimator;
duke@435 318 }
duke@435 319
duke@435 320 LinearLeastSquareFit* major_pause_young_estimator() {
duke@435 321 return _major_pause_young_estimator;
duke@435 322 }
duke@435 323
duke@435 324
duke@435 325 virtual void clear_generation_free_space_flags();
duke@435 326
duke@435 327 float major_pause_old_slope() { return _major_pause_old_estimator->slope(); }
duke@435 328 float major_pause_young_slope() {
duke@435 329 return _major_pause_young_estimator->slope();
duke@435 330 }
duke@435 331 float major_collection_slope() { return _major_collection_estimator->slope();}
duke@435 332
duke@435 333 bool old_gen_policy_is_ready() { return _old_gen_policy_is_ready; }
duke@435 334
duke@435 335 // Given the amount of live data in the heap, should we
duke@435 336 // perform a Full GC?
duke@435 337 bool should_full_GC(size_t live_in_old_gen);
duke@435 338
duke@435 339 // Calculates optimial free space sizes for both the old and young
duke@435 340 // generations. Stores results in _eden_size and _promo_size.
duke@435 341 // Takes current used space in all generations as input, as well
duke@435 342 // as an indication if a full gc has just been performed, for use
duke@435 343 // in deciding if an OOM error should be thrown.
duke@435 344 void compute_generation_free_space(size_t young_live,
duke@435 345 size_t eden_live,
duke@435 346 size_t old_live,
duke@435 347 size_t perm_live,
duke@435 348 size_t cur_eden, // current eden in bytes
duke@435 349 size_t max_old_gen_size,
duke@435 350 size_t max_eden_size,
duke@435 351 bool is_full_gc,
jmasa@1822 352 GCCause::Cause gc_cause,
jmasa@1822 353 CollectorPolicy* collector_policy);
duke@435 354
duke@435 355 // Calculates new survivor space size; returns a new tenuring threshold
duke@435 356 // value. Stores new survivor size in _survivor_size.
duke@435 357 int compute_survivor_space_size_and_threshold(bool is_survivor_overflow,
duke@435 358 int tenuring_threshold,
duke@435 359 size_t survivor_limit);
duke@435 360
duke@435 361 // Return the maximum size of a survivor space if the young generation were of
duke@435 362 // size gen_size.
duke@435 363 size_t max_survivor_size(size_t gen_size) {
duke@435 364 // Never allow the target survivor size to grow more than MinSurvivorRatio
duke@435 365 // of the young generation size. We cannot grow into a two semi-space
duke@435 366 // system, with Eden zero sized. Even if the survivor space grows, from()
duke@435 367 // might grow by moving the bottom boundary "down" -- so from space will
duke@435 368 // remain almost full anyway (top() will be near end(), but there will be a
duke@435 369 // large filler object at the bottom).
duke@435 370 const size_t sz = gen_size / MinSurvivorRatio;
duke@435 371 const size_t alignment = _intra_generation_alignment;
duke@435 372 return sz > alignment ? align_size_down(sz, alignment) : alignment;
duke@435 373 }
duke@435 374
duke@435 375 size_t live_at_last_full_gc() {
duke@435 376 return _live_at_last_full_gc;
duke@435 377 }
duke@435 378
duke@435 379 size_t bytes_absorbed_from_eden() const { return _bytes_absorbed_from_eden; }
duke@435 380 void reset_bytes_absorbed_from_eden() { _bytes_absorbed_from_eden = 0; }
duke@435 381
duke@435 382 void set_bytes_absorbed_from_eden(size_t val) {
duke@435 383 _bytes_absorbed_from_eden = val;
duke@435 384 }
duke@435 385
duke@435 386 // Update averages that are always used (even
duke@435 387 // if adaptive sizing is turned off).
duke@435 388 void update_averages(bool is_survivor_overflow,
duke@435 389 size_t survived,
duke@435 390 size_t promoted);
duke@435 391
duke@435 392 // Printing support
duke@435 393 virtual bool print_adaptive_size_policy_on(outputStream* st) const;
duke@435 394 };
stefank@2314 395
stefank@2314 396 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSADAPTIVESIZEPOLICY_HPP

mercurial