Thu, 20 Nov 2008 16:56:09 -0800
6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa
1 /*
2 * Copyright 2004-2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
25 // This class keeps statistical information and computes the
26 // size of the heap for the concurrent mark sweep collector.
27 //
28 // Cost for garbage collector include cost for
29 // minor collection
30 // concurrent collection
31 // stop-the-world component
32 // concurrent component
33 // major compacting collection
34 // uses decaying cost
36 // Forward decls
37 class elapsedTimer;
39 class CMSAdaptiveSizePolicy : public AdaptiveSizePolicy {
40 friend class CMSGCAdaptivePolicyCounters;
41 friend class CMSCollector;
42 private:
44 // Total number of processors available
45 int _processor_count;
46 // Number of processors used by the concurrent phases of GC
47 // This number is assumed to be the same for all concurrent
48 // phases.
49 int _concurrent_processor_count;
51 // Time that the mutators run exclusive of a particular
52 // phase. For example, the time the mutators run excluding
53 // the time during which the cms collector runs concurrently
54 // with the mutators.
55 // Between end of most recent cms reset and start of initial mark
56 // This may be redundant
57 double _latest_cms_reset_end_to_initial_mark_start_secs;
58 // Between end of the most recent initial mark and start of remark
59 double _latest_cms_initial_mark_end_to_remark_start_secs;
60 // Between end of most recent collection and start of
61 // a concurrent collection
62 double _latest_cms_collection_end_to_collection_start_secs;
63 // Times of the concurrent phases of the most recent
64 // concurrent collection
65 double _latest_cms_concurrent_marking_time_secs;
66 double _latest_cms_concurrent_precleaning_time_secs;
67 double _latest_cms_concurrent_sweeping_time_secs;
68 // Between end of most recent STW MSC and start of next STW MSC
69 double _latest_cms_msc_end_to_msc_start_time_secs;
70 // Between end of most recent MS and start of next MS
71 // This does not include any time spent during a concurrent
72 // collection.
73 double _latest_cms_ms_end_to_ms_start;
74 // Between start and end of the initial mark of the most recent
75 // concurrent collection.
76 double _latest_cms_initial_mark_start_to_end_time_secs;
77 // Between start and end of the remark phase of the most recent
78 // concurrent collection
79 double _latest_cms_remark_start_to_end_time_secs;
80 // Between start and end of the most recent MS STW marking phase
81 double _latest_cms_ms_marking_start_to_end_time_secs;
83 // Pause time timers
84 static elapsedTimer _STW_timer;
85 // Concurrent collection timer. Used for total of all concurrent phases
86 // during 1 collection cycle.
87 static elapsedTimer _concurrent_timer;
89 // When the size of the generation is changed, the size
90 // of the change will rounded up or down (depending on the
91 // type of change) by this value.
92 size_t _generation_alignment;
94 // If this variable is true, the size of the young generation
95 // may be changed in order to reduce the pause(s) of the
96 // collection of the tenured generation in order to meet the
97 // pause time goal. It is common to change the size of the
98 // tenured generation in order to meet the pause time goal
99 // for the tenured generation. With the CMS collector for
100 // the tenured generation, the size of the young generation
101 // can have an significant affect on the pause times for collecting the
102 // tenured generation.
103 // This is a duplicate of a variable in PSAdaptiveSizePolicy. It
104 // is duplicated because it is not clear that it is general enough
105 // to go into AdaptiveSizePolicy.
106 int _change_young_gen_for_maj_pauses;
108 // Variable that is set to true after a collection.
109 bool _first_after_collection;
111 // Fraction of collections that are of each type
112 double concurrent_fraction() const;
113 double STW_msc_fraction() const;
114 double STW_ms_fraction() const;
116 // This call cannot be put into the epilogue as long as some
117 // of the counters can be set during concurrent phases.
118 virtual void clear_generation_free_space_flags();
120 void set_first_after_collection() { _first_after_collection = true; }
122 protected:
123 // Average of the sum of the concurrent times for
124 // one collection in seconds.
125 AdaptiveWeightedAverage* _avg_concurrent_time;
126 // Average time between concurrent collections in seconds.
127 AdaptiveWeightedAverage* _avg_concurrent_interval;
128 // Average cost of the concurrent part of a collection
129 // in seconds.
130 AdaptiveWeightedAverage* _avg_concurrent_gc_cost;
132 // Average of the initial pause of a concurrent collection in seconds.
133 AdaptivePaddedAverage* _avg_initial_pause;
134 // Average of the remark pause of a concurrent collection in seconds.
135 AdaptivePaddedAverage* _avg_remark_pause;
137 // Average of the stop-the-world (STW) (initial mark + remark)
138 // times in seconds for concurrent collections.
139 AdaptiveWeightedAverage* _avg_cms_STW_time;
140 // Average of the STW collection cost for concurrent collections.
141 AdaptiveWeightedAverage* _avg_cms_STW_gc_cost;
143 // Average of the bytes free at the start of the sweep.
144 AdaptiveWeightedAverage* _avg_cms_free_at_sweep;
145 // Average of the bytes free at the end of the collection.
146 AdaptiveWeightedAverage* _avg_cms_free;
147 // Average of the bytes promoted between cms collections.
148 AdaptiveWeightedAverage* _avg_cms_promo;
150 // stop-the-world (STW) mark-sweep-compact
151 // Average of the pause time in seconds for STW mark-sweep-compact
152 // collections.
153 AdaptiveWeightedAverage* _avg_msc_pause;
154 // Average of the interval in seconds between STW mark-sweep-compact
155 // collections.
156 AdaptiveWeightedAverage* _avg_msc_interval;
157 // Average of the collection costs for STW mark-sweep-compact
158 // collections.
159 AdaptiveWeightedAverage* _avg_msc_gc_cost;
161 // Averages for mark-sweep collections.
162 // The collection may have started as a background collection
163 // that completes in a stop-the-world (STW) collection.
164 // Average of the pause time in seconds for mark-sweep
165 // collections.
166 AdaptiveWeightedAverage* _avg_ms_pause;
167 // Average of the interval in seconds between mark-sweep
168 // collections.
169 AdaptiveWeightedAverage* _avg_ms_interval;
170 // Average of the collection costs for mark-sweep
171 // collections.
172 AdaptiveWeightedAverage* _avg_ms_gc_cost;
174 // These variables contain a linear fit of
175 // a generation size as the independent variable
176 // and a pause time as the dependent variable.
177 // For example _remark_pause_old_estimator
178 // is a fit of the old generation size as the
179 // independent variable and the remark pause
180 // as the dependent variable.
181 // remark pause time vs. cms gen size
182 LinearLeastSquareFit* _remark_pause_old_estimator;
183 // initial pause time vs. cms gen size
184 LinearLeastSquareFit* _initial_pause_old_estimator;
185 // remark pause time vs. young gen size
186 LinearLeastSquareFit* _remark_pause_young_estimator;
187 // initial pause time vs. young gen size
188 LinearLeastSquareFit* _initial_pause_young_estimator;
190 // Accessors
191 int processor_count() const { return _processor_count; }
192 int concurrent_processor_count() const { return _concurrent_processor_count; }
194 AdaptiveWeightedAverage* avg_concurrent_time() const {
195 return _avg_concurrent_time;
196 }
198 AdaptiveWeightedAverage* avg_concurrent_interval() const {
199 return _avg_concurrent_interval;
200 }
202 AdaptiveWeightedAverage* avg_concurrent_gc_cost() const {
203 return _avg_concurrent_gc_cost;
204 }
206 AdaptiveWeightedAverage* avg_cms_STW_time() const {
207 return _avg_cms_STW_time;
208 }
210 AdaptiveWeightedAverage* avg_cms_STW_gc_cost() const {
211 return _avg_cms_STW_gc_cost;
212 }
214 AdaptivePaddedAverage* avg_initial_pause() const {
215 return _avg_initial_pause;
216 }
218 AdaptivePaddedAverage* avg_remark_pause() const {
219 return _avg_remark_pause;
220 }
222 AdaptiveWeightedAverage* avg_cms_free() const {
223 return _avg_cms_free;
224 }
226 AdaptiveWeightedAverage* avg_cms_free_at_sweep() const {
227 return _avg_cms_free_at_sweep;
228 }
230 AdaptiveWeightedAverage* avg_msc_pause() const {
231 return _avg_msc_pause;
232 }
234 AdaptiveWeightedAverage* avg_msc_interval() const {
235 return _avg_msc_interval;
236 }
238 AdaptiveWeightedAverage* avg_msc_gc_cost() const {
239 return _avg_msc_gc_cost;
240 }
242 AdaptiveWeightedAverage* avg_ms_pause() const {
243 return _avg_ms_pause;
244 }
246 AdaptiveWeightedAverage* avg_ms_interval() const {
247 return _avg_ms_interval;
248 }
250 AdaptiveWeightedAverage* avg_ms_gc_cost() const {
251 return _avg_ms_gc_cost;
252 }
254 LinearLeastSquareFit* remark_pause_old_estimator() {
255 return _remark_pause_old_estimator;
256 }
257 LinearLeastSquareFit* initial_pause_old_estimator() {
258 return _initial_pause_old_estimator;
259 }
260 LinearLeastSquareFit* remark_pause_young_estimator() {
261 return _remark_pause_young_estimator;
262 }
263 LinearLeastSquareFit* initial_pause_young_estimator() {
264 return _initial_pause_young_estimator;
265 }
267 // These *slope() methods return the slope
268 // m for the linear fit of an independent
269 // variable vs. a dependent variable. For
270 // example
271 // remark_pause = m * old_generation_size + c
272 // These may be used to determine if an
273 // adjustment should be made to achieve a goal.
274 // For example, if remark_pause_old_slope() is
275 // positive, a reduction of the old generation
276 // size has on average resulted in the reduction
277 // of the remark pause.
278 float remark_pause_old_slope() {
279 return _remark_pause_old_estimator->slope();
280 }
282 float initial_pause_old_slope() {
283 return _initial_pause_old_estimator->slope();
284 }
286 float remark_pause_young_slope() {
287 return _remark_pause_young_estimator->slope();
288 }
290 float initial_pause_young_slope() {
291 return _initial_pause_young_estimator->slope();
292 }
294 // Update estimators
295 void update_minor_pause_old_estimator(double minor_pause_in_ms);
297 // Fraction of processors used by the concurrent phases.
298 double concurrent_processor_fraction();
300 // Returns the total times for the concurrent part of the
301 // latest collection in seconds.
302 double concurrent_collection_time();
304 // Return the total times for the concurrent part of the
305 // latest collection in seconds where the times of the various
306 // concurrent phases are scaled by the processor fraction used
307 // during the phase.
308 double scaled_concurrent_collection_time();
310 // Dimensionless concurrent GC cost for all the concurrent phases.
311 double concurrent_collection_cost(double interval_in_seconds);
313 // Dimensionless GC cost
314 double collection_cost(double pause_in_seconds, double interval_in_seconds);
316 virtual GCPolicyKind kind() const { return _gc_cms_adaptive_size_policy; }
318 virtual double time_since_major_gc() const;
320 // This returns the maximum average for the concurrent, ms, and
321 // msc collections. This is meant to be used for the calculation
322 // of the decayed major gc cost and is not in general the
323 // average of all the different types of major collections.
324 virtual double major_gc_interval_average_for_decay() const;
326 public:
327 CMSAdaptiveSizePolicy(size_t init_eden_size,
328 size_t init_promo_size,
329 size_t init_survivor_size,
330 double max_gc_minor_pause_sec,
331 double max_gc_pause_sec,
332 uint gc_cost_ratio);
334 // The timers for the stop-the-world phases measure a total
335 // stop-the-world time. The timer is started and stopped
336 // for each phase but is only reset after the final checkpoint.
337 void checkpoint_roots_initial_begin();
338 void checkpoint_roots_initial_end(GCCause::Cause gc_cause);
339 void checkpoint_roots_final_begin();
340 void checkpoint_roots_final_end(GCCause::Cause gc_cause);
342 // Methods for gathering information about the
343 // concurrent marking phase of the collection.
344 // Records the mutator times and
345 // resets the concurrent timer.
346 void concurrent_marking_begin();
347 // Resets concurrent phase timer in the begin methods and
348 // saves the time for a phase in the end methods.
349 void concurrent_marking_end();
350 void concurrent_sweeping_begin();
351 void concurrent_sweeping_end();
352 // Similar to the above (e.g., concurrent_marking_end()) and
353 // is used for both the precleaning an abortable precleaing
354 // phases.
355 void concurrent_precleaning_begin();
356 void concurrent_precleaning_end();
357 // Stops the concurrent phases time. Gathers
358 // information and resets the timer.
359 void concurrent_phases_end(GCCause::Cause gc_cause,
360 size_t cur_eden,
361 size_t cur_promo);
363 // Methods for gather information about STW Mark-Sweep-Compact
364 void msc_collection_begin();
365 void msc_collection_end(GCCause::Cause gc_cause);
367 // Methods for gather information about Mark-Sweep done
368 // in the foreground.
369 void ms_collection_begin();
370 void ms_collection_end(GCCause::Cause gc_cause);
372 // Cost for a mark-sweep tenured gen collection done in the foreground
373 double ms_gc_cost() const {
374 return MAX2(0.0F, _avg_ms_gc_cost->average());
375 }
377 // Cost of collecting the tenured generation. Includes
378 // concurrent collection and STW collection costs
379 double cms_gc_cost() const;
381 // Cost of STW mark-sweep-compact tenured gen collection.
382 double msc_gc_cost() const {
383 return MAX2(0.0F, _avg_msc_gc_cost->average());
384 }
386 //
387 double compacting_gc_cost() const {
388 double result = MIN2(1.0, minor_gc_cost() + msc_gc_cost());
389 assert(result >= 0.0, "Both minor and major costs are non-negative");
390 return result;
391 }
393 // Restarts the concurrent phases timer.
394 void concurrent_phases_resume();
396 // Time begining and end of the marking phase for
397 // a synchronous MS collection. A MS collection
398 // that finishes in the foreground can have started
399 // in the background. These methods capture the
400 // completion of the marking (after the initial
401 // marking) that is done in the foreground.
402 void ms_collection_marking_begin();
403 void ms_collection_marking_end(GCCause::Cause gc_cause);
405 static elapsedTimer* concurrent_timer_ptr() {
406 return &_concurrent_timer;
407 }
409 AdaptiveWeightedAverage* avg_cms_promo() const {
410 return _avg_cms_promo;
411 }
413 int change_young_gen_for_maj_pauses() {
414 return _change_young_gen_for_maj_pauses;
415 }
416 void set_change_young_gen_for_maj_pauses(int v) {
417 _change_young_gen_for_maj_pauses = v;
418 }
420 void clear_internal_time_intervals();
423 // Either calculated_promo_size_in_bytes() or promo_size()
424 // should be deleted.
425 size_t promo_size() { return _promo_size; }
426 void set_promo_size(size_t v) { _promo_size = v; }
428 // Cost of GC for all types of collections.
429 virtual double gc_cost() const;
431 size_t generation_alignment() { return _generation_alignment; }
433 virtual void compute_young_generation_free_space(size_t cur_eden,
434 size_t max_eden_size);
435 // Calculates new survivor space size; returns a new tenuring threshold
436 // value. Stores new survivor size in _survivor_size.
437 virtual int compute_survivor_space_size_and_threshold(
438 bool is_survivor_overflow,
439 int tenuring_threshold,
440 size_t survivor_limit);
442 virtual void compute_tenured_generation_free_space(size_t cur_tenured_free,
443 size_t max_tenured_available,
444 size_t cur_eden);
446 size_t eden_decrement_aligned_down(size_t cur_eden);
447 size_t eden_increment_aligned_up(size_t cur_eden);
449 size_t adjust_eden_for_pause_time(size_t cur_eden);
450 size_t adjust_eden_for_throughput(size_t cur_eden);
451 size_t adjust_eden_for_footprint(size_t cur_eden);
453 size_t promo_decrement_aligned_down(size_t cur_promo);
454 size_t promo_increment_aligned_up(size_t cur_promo);
456 size_t adjust_promo_for_pause_time(size_t cur_promo);
457 size_t adjust_promo_for_throughput(size_t cur_promo);
458 size_t adjust_promo_for_footprint(size_t cur_promo, size_t cur_eden);
460 // Scale down the input size by the ratio of the cost to collect the
461 // generation to the total GC cost.
462 size_t scale_by_gen_gc_cost(size_t base_change, double gen_gc_cost);
464 // Return the value and clear it.
465 bool get_and_clear_first_after_collection();
467 // Printing support
468 virtual bool print_adaptive_size_policy_on(outputStream* st) const;
469 };