Wed, 23 Dec 2009 09:23:54 -0800
6631166: CMS: better heuristics when combatting fragmentation
Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking.
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 */
24 #include "incls/_precompiled.incl"
25 #include "incls/_cmsAdaptiveSizePolicy.cpp.incl"
27 elapsedTimer CMSAdaptiveSizePolicy::_concurrent_timer;
28 elapsedTimer CMSAdaptiveSizePolicy::_STW_timer;
30 // Defined if the granularity of the time measurements is potentially too large.
31 #define CLOCK_GRANULARITY_TOO_LARGE
33 CMSAdaptiveSizePolicy::CMSAdaptiveSizePolicy(size_t init_eden_size,
34 size_t init_promo_size,
35 size_t init_survivor_size,
36 double max_gc_minor_pause_sec,
37 double max_gc_pause_sec,
38 uint gc_cost_ratio) :
39 AdaptiveSizePolicy(init_eden_size,
40 init_promo_size,
41 init_survivor_size,
42 max_gc_pause_sec,
43 gc_cost_ratio) {
45 clear_internal_time_intervals();
47 _processor_count = os::active_processor_count();
49 if (CMSConcurrentMTEnabled && (ParallelCMSThreads > 1)) {
50 assert(_processor_count > 0, "Processor count is suspect");
51 _concurrent_processor_count = MIN2((uint) ParallelCMSThreads,
52 (uint) _processor_count);
53 } else {
54 _concurrent_processor_count = 1;
55 }
57 _avg_concurrent_time = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
58 _avg_concurrent_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
59 _avg_concurrent_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
61 _avg_initial_pause = new AdaptivePaddedAverage(AdaptiveTimeWeight,
62 PausePadding);
63 _avg_remark_pause = new AdaptivePaddedAverage(AdaptiveTimeWeight,
64 PausePadding);
66 _avg_cms_STW_time = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
67 _avg_cms_STW_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
69 _avg_cms_free = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
70 _avg_cms_free_at_sweep = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
71 _avg_cms_promo = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
73 // Mark-sweep-compact
74 _avg_msc_pause = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
75 _avg_msc_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
76 _avg_msc_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
78 // Mark-sweep
79 _avg_ms_pause = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
80 _avg_ms_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
81 _avg_ms_gc_cost = new AdaptiveWeightedAverage(AdaptiveTimeWeight);
83 // Variables that estimate pause times as a function of generation
84 // size.
85 _remark_pause_old_estimator =
86 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
87 _initial_pause_old_estimator =
88 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
89 _remark_pause_young_estimator =
90 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
91 _initial_pause_young_estimator =
92 new LinearLeastSquareFit(AdaptiveSizePolicyWeight);
94 // Alignment comes from that used in ReservedSpace.
95 _generation_alignment = os::vm_allocation_granularity();
97 // Start the concurrent timer here so that the first
98 // concurrent_phases_begin() measures a finite mutator
99 // time. A finite mutator time is used to determine
100 // if a concurrent collection has been started. If this
101 // proves to be a problem, use some explicit flag to
102 // signal that a concurrent collection has been started.
103 _concurrent_timer.start();
104 _STW_timer.start();
105 }
107 double CMSAdaptiveSizePolicy::concurrent_processor_fraction() {
108 // For now assume no other daemon threads are taking alway
109 // cpu's from the application.
110 return ((double) _concurrent_processor_count / (double) _processor_count);
111 }
113 double CMSAdaptiveSizePolicy::concurrent_collection_cost(
114 double interval_in_seconds) {
115 // When the precleaning and sweeping phases use multiple
116 // threads, change one_processor_fraction to
117 // concurrent_processor_fraction().
118 double one_processor_fraction = 1.0 / ((double) processor_count());
119 double concurrent_cost =
120 collection_cost(_latest_cms_concurrent_marking_time_secs,
121 interval_in_seconds) * concurrent_processor_fraction() +
122 collection_cost(_latest_cms_concurrent_precleaning_time_secs,
123 interval_in_seconds) * one_processor_fraction +
124 collection_cost(_latest_cms_concurrent_sweeping_time_secs,
125 interval_in_seconds) * one_processor_fraction;
126 if (PrintAdaptiveSizePolicy && Verbose) {
127 gclog_or_tty->print_cr(
128 "\nCMSAdaptiveSizePolicy::scaled_concurrent_collection_cost(%f) "
129 "_latest_cms_concurrent_marking_cost %f "
130 "_latest_cms_concurrent_precleaning_cost %f "
131 "_latest_cms_concurrent_sweeping_cost %f "
132 "concurrent_processor_fraction %f "
133 "concurrent_cost %f ",
134 interval_in_seconds,
135 collection_cost(_latest_cms_concurrent_marking_time_secs,
136 interval_in_seconds),
137 collection_cost(_latest_cms_concurrent_precleaning_time_secs,
138 interval_in_seconds),
139 collection_cost(_latest_cms_concurrent_sweeping_time_secs,
140 interval_in_seconds),
141 concurrent_processor_fraction(),
142 concurrent_cost);
143 }
144 return concurrent_cost;
145 }
147 double CMSAdaptiveSizePolicy::concurrent_collection_time() {
148 double latest_cms_sum_concurrent_phases_time_secs =
149 _latest_cms_concurrent_marking_time_secs +
150 _latest_cms_concurrent_precleaning_time_secs +
151 _latest_cms_concurrent_sweeping_time_secs;
152 return latest_cms_sum_concurrent_phases_time_secs;
153 }
155 double CMSAdaptiveSizePolicy::scaled_concurrent_collection_time() {
156 // When the precleaning and sweeping phases use multiple
157 // threads, change one_processor_fraction to
158 // concurrent_processor_fraction().
159 double one_processor_fraction = 1.0 / ((double) processor_count());
160 double latest_cms_sum_concurrent_phases_time_secs =
161 _latest_cms_concurrent_marking_time_secs * concurrent_processor_fraction() +
162 _latest_cms_concurrent_precleaning_time_secs * one_processor_fraction +
163 _latest_cms_concurrent_sweeping_time_secs * one_processor_fraction ;
164 if (PrintAdaptiveSizePolicy && Verbose) {
165 gclog_or_tty->print_cr(
166 "\nCMSAdaptiveSizePolicy::scaled_concurrent_collection_time "
167 "_latest_cms_concurrent_marking_time_secs %f "
168 "_latest_cms_concurrent_precleaning_time_secs %f "
169 "_latest_cms_concurrent_sweeping_time_secs %f "
170 "concurrent_processor_fraction %f "
171 "latest_cms_sum_concurrent_phases_time_secs %f ",
172 _latest_cms_concurrent_marking_time_secs,
173 _latest_cms_concurrent_precleaning_time_secs,
174 _latest_cms_concurrent_sweeping_time_secs,
175 concurrent_processor_fraction(),
176 latest_cms_sum_concurrent_phases_time_secs);
177 }
178 return latest_cms_sum_concurrent_phases_time_secs;
179 }
181 void CMSAdaptiveSizePolicy::update_minor_pause_old_estimator(
182 double minor_pause_in_ms) {
183 // Get the equivalent of the free space
184 // that is available for promotions in the CMS generation
185 // and use that to update _minor_pause_old_estimator
187 // Don't implement this until it is needed. A warning is
188 // printed if _minor_pause_old_estimator is used.
189 }
191 void CMSAdaptiveSizePolicy::concurrent_marking_begin() {
192 if (PrintAdaptiveSizePolicy && Verbose) {
193 gclog_or_tty->print(" ");
194 gclog_or_tty->stamp();
195 gclog_or_tty->print(": concurrent_marking_begin ");
196 }
197 // Update the interval time
198 _concurrent_timer.stop();
199 _latest_cms_collection_end_to_collection_start_secs = _concurrent_timer.seconds();
200 if (PrintAdaptiveSizePolicy && Verbose) {
201 gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_marking_begin: "
202 "mutator time %f", _latest_cms_collection_end_to_collection_start_secs);
203 }
204 _concurrent_timer.reset();
205 _concurrent_timer.start();
206 }
208 void CMSAdaptiveSizePolicy::concurrent_marking_end() {
209 if (PrintAdaptiveSizePolicy && Verbose) {
210 gclog_or_tty->stamp();
211 gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_marking_end()");
212 }
214 _concurrent_timer.stop();
215 _latest_cms_concurrent_marking_time_secs = _concurrent_timer.seconds();
217 if (PrintAdaptiveSizePolicy && Verbose) {
218 gclog_or_tty->print_cr("\n CMSAdaptiveSizePolicy::concurrent_marking_end"
219 ":concurrent marking time (s) %f",
220 _latest_cms_concurrent_marking_time_secs);
221 }
222 }
224 void CMSAdaptiveSizePolicy::concurrent_precleaning_begin() {
225 if (PrintAdaptiveSizePolicy && Verbose) {
226 gclog_or_tty->stamp();
227 gclog_or_tty->print_cr(
228 "CMSAdaptiveSizePolicy::concurrent_precleaning_begin()");
229 }
230 _concurrent_timer.reset();
231 _concurrent_timer.start();
232 }
235 void CMSAdaptiveSizePolicy::concurrent_precleaning_end() {
236 if (PrintAdaptiveSizePolicy && Verbose) {
237 gclog_or_tty->stamp();
238 gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_precleaning_end()");
239 }
241 _concurrent_timer.stop();
242 // May be set again by a second call during the same collection.
243 _latest_cms_concurrent_precleaning_time_secs = _concurrent_timer.seconds();
245 if (PrintAdaptiveSizePolicy && Verbose) {
246 gclog_or_tty->print_cr("\n CMSAdaptiveSizePolicy::concurrent_precleaning_end"
247 ":concurrent precleaning time (s) %f",
248 _latest_cms_concurrent_precleaning_time_secs);
249 }
250 }
252 void CMSAdaptiveSizePolicy::concurrent_sweeping_begin() {
253 if (PrintAdaptiveSizePolicy && Verbose) {
254 gclog_or_tty->stamp();
255 gclog_or_tty->print_cr(
256 "CMSAdaptiveSizePolicy::concurrent_sweeping_begin()");
257 }
258 _concurrent_timer.reset();
259 _concurrent_timer.start();
260 }
263 void CMSAdaptiveSizePolicy::concurrent_sweeping_end() {
264 if (PrintAdaptiveSizePolicy && Verbose) {
265 gclog_or_tty->stamp();
266 gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_sweeping_end()");
267 }
269 _concurrent_timer.stop();
270 _latest_cms_concurrent_sweeping_time_secs = _concurrent_timer.seconds();
272 if (PrintAdaptiveSizePolicy && Verbose) {
273 gclog_or_tty->print_cr("\n CMSAdaptiveSizePolicy::concurrent_sweeping_end"
274 ":concurrent sweeping time (s) %f",
275 _latest_cms_concurrent_sweeping_time_secs);
276 }
277 }
279 void CMSAdaptiveSizePolicy::concurrent_phases_end(GCCause::Cause gc_cause,
280 size_t cur_eden,
281 size_t cur_promo) {
282 if (PrintAdaptiveSizePolicy && Verbose) {
283 gclog_or_tty->print(" ");
284 gclog_or_tty->stamp();
285 gclog_or_tty->print(": concurrent_phases_end ");
286 }
288 // Update the concurrent timer
289 _concurrent_timer.stop();
291 if (gc_cause != GCCause::_java_lang_system_gc ||
292 UseAdaptiveSizePolicyWithSystemGC) {
294 avg_cms_free()->sample(cur_promo);
295 double latest_cms_sum_concurrent_phases_time_secs =
296 concurrent_collection_time();
298 _avg_concurrent_time->sample(latest_cms_sum_concurrent_phases_time_secs);
300 // Cost of collection (unit-less)
302 // Total interval for collection. May not be valid. Tests
303 // below determine whether to use this.
304 //
305 if (PrintAdaptiveSizePolicy && Verbose) {
306 gclog_or_tty->print_cr("\nCMSAdaptiveSizePolicy::concurrent_phases_end \n"
307 "_latest_cms_reset_end_to_initial_mark_start_secs %f \n"
308 "_latest_cms_initial_mark_start_to_end_time_secs %f \n"
309 "_latest_cms_remark_start_to_end_time_secs %f \n"
310 "_latest_cms_concurrent_marking_time_secs %f \n"
311 "_latest_cms_concurrent_precleaning_time_secs %f \n"
312 "_latest_cms_concurrent_sweeping_time_secs %f \n"
313 "latest_cms_sum_concurrent_phases_time_secs %f \n"
314 "_latest_cms_collection_end_to_collection_start_secs %f \n"
315 "concurrent_processor_fraction %f",
316 _latest_cms_reset_end_to_initial_mark_start_secs,
317 _latest_cms_initial_mark_start_to_end_time_secs,
318 _latest_cms_remark_start_to_end_time_secs,
319 _latest_cms_concurrent_marking_time_secs,
320 _latest_cms_concurrent_precleaning_time_secs,
321 _latest_cms_concurrent_sweeping_time_secs,
322 latest_cms_sum_concurrent_phases_time_secs,
323 _latest_cms_collection_end_to_collection_start_secs,
324 concurrent_processor_fraction());
325 }
326 double interval_in_seconds =
327 _latest_cms_initial_mark_start_to_end_time_secs +
328 _latest_cms_remark_start_to_end_time_secs +
329 latest_cms_sum_concurrent_phases_time_secs +
330 _latest_cms_collection_end_to_collection_start_secs;
331 assert(interval_in_seconds >= 0.0,
332 "Bad interval between cms collections");
334 // Sample for performance counter
335 avg_concurrent_interval()->sample(interval_in_seconds);
337 // STW costs (initial and remark pauses)
338 // Cost of collection (unit-less)
339 assert(_latest_cms_initial_mark_start_to_end_time_secs >= 0.0,
340 "Bad initial mark pause");
341 assert(_latest_cms_remark_start_to_end_time_secs >= 0.0,
342 "Bad remark pause");
343 double STW_time_in_seconds =
344 _latest_cms_initial_mark_start_to_end_time_secs +
345 _latest_cms_remark_start_to_end_time_secs;
346 double STW_collection_cost = 0.0;
347 if (interval_in_seconds > 0.0) {
348 // cost for the STW phases of the concurrent collection.
349 STW_collection_cost = STW_time_in_seconds / interval_in_seconds;
350 avg_cms_STW_gc_cost()->sample(STW_collection_cost);
351 }
352 if (PrintAdaptiveSizePolicy && Verbose) {
353 gclog_or_tty->print("cmsAdaptiveSizePolicy::STW_collection_end: "
354 "STW gc cost: %f average: %f", STW_collection_cost,
355 avg_cms_STW_gc_cost()->average());
356 gclog_or_tty->print_cr(" STW pause: %f (ms) STW period %f (ms)",
357 (double) STW_time_in_seconds * MILLIUNITS,
358 (double) interval_in_seconds * MILLIUNITS);
359 }
361 double concurrent_cost = 0.0;
362 if (latest_cms_sum_concurrent_phases_time_secs > 0.0) {
363 concurrent_cost = concurrent_collection_cost(interval_in_seconds);
365 avg_concurrent_gc_cost()->sample(concurrent_cost);
366 // Average this ms cost into all the other types gc costs
368 if (PrintAdaptiveSizePolicy && Verbose) {
369 gclog_or_tty->print("cmsAdaptiveSizePolicy::concurrent_phases_end: "
370 "concurrent gc cost: %f average: %f",
371 concurrent_cost,
372 _avg_concurrent_gc_cost->average());
373 gclog_or_tty->print_cr(" concurrent time: %f (ms) cms period %f (ms)"
374 " processor fraction: %f",
375 latest_cms_sum_concurrent_phases_time_secs * MILLIUNITS,
376 interval_in_seconds * MILLIUNITS,
377 concurrent_processor_fraction());
378 }
379 }
380 double total_collection_cost = STW_collection_cost + concurrent_cost;
381 avg_major_gc_cost()->sample(total_collection_cost);
383 // Gather information for estimating future behavior
384 double initial_pause_in_ms = _latest_cms_initial_mark_start_to_end_time_secs * MILLIUNITS;
385 double remark_pause_in_ms = _latest_cms_remark_start_to_end_time_secs * MILLIUNITS;
387 double cur_promo_size_in_mbytes = ((double)cur_promo)/((double)M);
388 initial_pause_old_estimator()->update(cur_promo_size_in_mbytes,
389 initial_pause_in_ms);
390 remark_pause_old_estimator()->update(cur_promo_size_in_mbytes,
391 remark_pause_in_ms);
392 major_collection_estimator()->update(cur_promo_size_in_mbytes,
393 total_collection_cost);
395 // This estimate uses the average eden size. It could also
396 // have used the latest eden size. Which is better?
397 double cur_eden_size_in_mbytes = ((double)cur_eden)/((double) M);
398 initial_pause_young_estimator()->update(cur_eden_size_in_mbytes,
399 initial_pause_in_ms);
400 remark_pause_young_estimator()->update(cur_eden_size_in_mbytes,
401 remark_pause_in_ms);
402 }
404 clear_internal_time_intervals();
406 set_first_after_collection();
408 // The concurrent phases keeps track of it's own mutator interval
409 // with this timer. This allows the stop-the-world phase to
410 // be included in the mutator time so that the stop-the-world time
411 // is not double counted. Reset and start it.
412 _concurrent_timer.reset();
413 _concurrent_timer.start();
415 // The mutator time between STW phases does not include the
416 // concurrent collection time.
417 _STW_timer.reset();
418 _STW_timer.start();
419 }
421 void CMSAdaptiveSizePolicy::checkpoint_roots_initial_begin() {
422 // Update the interval time
423 _STW_timer.stop();
424 _latest_cms_reset_end_to_initial_mark_start_secs = _STW_timer.seconds();
425 // Reset for the initial mark
426 _STW_timer.reset();
427 _STW_timer.start();
428 }
430 void CMSAdaptiveSizePolicy::checkpoint_roots_initial_end(
431 GCCause::Cause gc_cause) {
432 _STW_timer.stop();
434 if (gc_cause != GCCause::_java_lang_system_gc ||
435 UseAdaptiveSizePolicyWithSystemGC) {
436 _latest_cms_initial_mark_start_to_end_time_secs = _STW_timer.seconds();
437 avg_initial_pause()->sample(_latest_cms_initial_mark_start_to_end_time_secs);
439 if (PrintAdaptiveSizePolicy && Verbose) {
440 gclog_or_tty->print(
441 "cmsAdaptiveSizePolicy::checkpoint_roots_initial_end: "
442 "initial pause: %f ", _latest_cms_initial_mark_start_to_end_time_secs);
443 }
444 }
446 _STW_timer.reset();
447 _STW_timer.start();
448 }
450 void CMSAdaptiveSizePolicy::checkpoint_roots_final_begin() {
451 _STW_timer.stop();
452 _latest_cms_initial_mark_end_to_remark_start_secs = _STW_timer.seconds();
453 // Start accumumlating time for the remark in the STW timer.
454 _STW_timer.reset();
455 _STW_timer.start();
456 }
458 void CMSAdaptiveSizePolicy::checkpoint_roots_final_end(
459 GCCause::Cause gc_cause) {
460 _STW_timer.stop();
461 if (gc_cause != GCCause::_java_lang_system_gc ||
462 UseAdaptiveSizePolicyWithSystemGC) {
463 // Total initial mark pause + remark pause.
464 _latest_cms_remark_start_to_end_time_secs = _STW_timer.seconds();
465 double STW_time_in_seconds = _latest_cms_initial_mark_start_to_end_time_secs +
466 _latest_cms_remark_start_to_end_time_secs;
467 double STW_time_in_ms = STW_time_in_seconds * MILLIUNITS;
469 avg_remark_pause()->sample(_latest_cms_remark_start_to_end_time_secs);
471 // Sample total for initial mark + remark
472 avg_cms_STW_time()->sample(STW_time_in_seconds);
474 if (PrintAdaptiveSizePolicy && Verbose) {
475 gclog_or_tty->print("cmsAdaptiveSizePolicy::checkpoint_roots_final_end: "
476 "remark pause: %f", _latest_cms_remark_start_to_end_time_secs);
477 }
479 }
480 // Don't start the STW times here because the concurrent
481 // sweep and reset has not happened.
482 // Keep the old comment above in case I don't understand
483 // what is going on but now
484 // Start the STW timer because it is used by ms_collection_begin()
485 // and ms_collection_end() to get the sweep time if a MS is being
486 // done in the foreground.
487 _STW_timer.reset();
488 _STW_timer.start();
489 }
491 void CMSAdaptiveSizePolicy::msc_collection_begin() {
492 if (PrintAdaptiveSizePolicy && Verbose) {
493 gclog_or_tty->print(" ");
494 gclog_or_tty->stamp();
495 gclog_or_tty->print(": msc_collection_begin ");
496 }
497 _STW_timer.stop();
498 _latest_cms_msc_end_to_msc_start_time_secs = _STW_timer.seconds();
499 if (PrintAdaptiveSizePolicy && Verbose) {
500 gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::msc_collection_begin: "
501 "mutator time %f",
502 _latest_cms_msc_end_to_msc_start_time_secs);
503 }
504 avg_msc_interval()->sample(_latest_cms_msc_end_to_msc_start_time_secs);
505 _STW_timer.reset();
506 _STW_timer.start();
507 }
509 void CMSAdaptiveSizePolicy::msc_collection_end(GCCause::Cause gc_cause) {
510 if (PrintAdaptiveSizePolicy && Verbose) {
511 gclog_or_tty->print(" ");
512 gclog_or_tty->stamp();
513 gclog_or_tty->print(": msc_collection_end ");
514 }
515 _STW_timer.stop();
516 if (gc_cause != GCCause::_java_lang_system_gc ||
517 UseAdaptiveSizePolicyWithSystemGC) {
518 double msc_pause_in_seconds = _STW_timer.seconds();
519 if ((_latest_cms_msc_end_to_msc_start_time_secs > 0.0) &&
520 (msc_pause_in_seconds > 0.0)) {
521 avg_msc_pause()->sample(msc_pause_in_seconds);
522 double mutator_time_in_seconds = 0.0;
523 if (_latest_cms_collection_end_to_collection_start_secs == 0.0) {
524 // This assertion may fail because of time stamp gradularity.
525 // Comment it out and investiage it at a later time. The large
526 // time stamp granularity occurs on some older linux systems.
527 #ifndef CLOCK_GRANULARITY_TOO_LARGE
528 assert((_latest_cms_concurrent_marking_time_secs == 0.0) &&
529 (_latest_cms_concurrent_precleaning_time_secs == 0.0) &&
530 (_latest_cms_concurrent_sweeping_time_secs == 0.0),
531 "There should not be any concurrent time");
532 #endif
533 // A concurrent collection did not start. Mutator time
534 // between collections comes from the STW MSC timer.
535 mutator_time_in_seconds = _latest_cms_msc_end_to_msc_start_time_secs;
536 } else {
537 // The concurrent collection did start so count the mutator
538 // time to the start of the concurrent collection. In this
539 // case the _latest_cms_msc_end_to_msc_start_time_secs measures
540 // the time between the initial mark or remark and the
541 // start of the MSC. That has no real meaning.
542 mutator_time_in_seconds = _latest_cms_collection_end_to_collection_start_secs;
543 }
545 double latest_cms_sum_concurrent_phases_time_secs =
546 concurrent_collection_time();
547 double interval_in_seconds =
548 mutator_time_in_seconds +
549 _latest_cms_initial_mark_start_to_end_time_secs +
550 _latest_cms_remark_start_to_end_time_secs +
551 latest_cms_sum_concurrent_phases_time_secs +
552 msc_pause_in_seconds;
554 if (PrintAdaptiveSizePolicy && Verbose) {
555 gclog_or_tty->print_cr(" interval_in_seconds %f \n"
556 " mutator_time_in_seconds %f \n"
557 " _latest_cms_initial_mark_start_to_end_time_secs %f\n"
558 " _latest_cms_remark_start_to_end_time_secs %f\n"
559 " latest_cms_sum_concurrent_phases_time_secs %f\n"
560 " msc_pause_in_seconds %f\n",
561 interval_in_seconds,
562 mutator_time_in_seconds,
563 _latest_cms_initial_mark_start_to_end_time_secs,
564 _latest_cms_remark_start_to_end_time_secs,
565 latest_cms_sum_concurrent_phases_time_secs,
566 msc_pause_in_seconds);
567 }
569 // The concurrent cost is wasted cost but it should be
570 // included.
571 double concurrent_cost = concurrent_collection_cost(interval_in_seconds);
573 // Initial mark and remark, also wasted.
574 double STW_time_in_seconds = _latest_cms_initial_mark_start_to_end_time_secs +
575 _latest_cms_remark_start_to_end_time_secs;
576 double STW_collection_cost =
577 collection_cost(STW_time_in_seconds, interval_in_seconds) +
578 concurrent_cost;
580 if (PrintAdaptiveSizePolicy && Verbose) {
581 gclog_or_tty->print_cr(" msc_collection_end:\n"
582 "_latest_cms_collection_end_to_collection_start_secs %f\n"
583 "_latest_cms_msc_end_to_msc_start_time_secs %f\n"
584 "_latest_cms_initial_mark_start_to_end_time_secs %f\n"
585 "_latest_cms_remark_start_to_end_time_secs %f\n"
586 "latest_cms_sum_concurrent_phases_time_secs %f\n",
587 _latest_cms_collection_end_to_collection_start_secs,
588 _latest_cms_msc_end_to_msc_start_time_secs,
589 _latest_cms_initial_mark_start_to_end_time_secs,
590 _latest_cms_remark_start_to_end_time_secs,
591 latest_cms_sum_concurrent_phases_time_secs);
593 gclog_or_tty->print_cr(" msc_collection_end: \n"
594 "latest_cms_sum_concurrent_phases_time_secs %f\n"
595 "STW_time_in_seconds %f\n"
596 "msc_pause_in_seconds %f\n",
597 latest_cms_sum_concurrent_phases_time_secs,
598 STW_time_in_seconds,
599 msc_pause_in_seconds);
600 }
602 double cost = concurrent_cost + STW_collection_cost +
603 collection_cost(msc_pause_in_seconds, interval_in_seconds);
605 _avg_msc_gc_cost->sample(cost);
607 // Average this ms cost into all the other types gc costs
608 avg_major_gc_cost()->sample(cost);
610 // Sample for performance counter
611 _avg_msc_interval->sample(interval_in_seconds);
612 if (PrintAdaptiveSizePolicy && Verbose) {
613 gclog_or_tty->print("cmsAdaptiveSizePolicy::msc_collection_end: "
614 "MSC gc cost: %f average: %f", cost,
615 _avg_msc_gc_cost->average());
617 double msc_pause_in_ms = msc_pause_in_seconds * MILLIUNITS;
618 gclog_or_tty->print_cr(" MSC pause: %f (ms) MSC period %f (ms)",
619 msc_pause_in_ms, (double) interval_in_seconds * MILLIUNITS);
620 }
621 }
622 }
624 clear_internal_time_intervals();
626 // Can this call be put into the epilogue?
627 set_first_after_collection();
629 // The concurrent phases keeps track of it's own mutator interval
630 // with this timer. This allows the stop-the-world phase to
631 // be included in the mutator time so that the stop-the-world time
632 // is not double counted. Reset and start it.
633 _concurrent_timer.stop();
634 _concurrent_timer.reset();
635 _concurrent_timer.start();
637 _STW_timer.reset();
638 _STW_timer.start();
639 }
641 void CMSAdaptiveSizePolicy::ms_collection_begin() {
642 if (PrintAdaptiveSizePolicy && Verbose) {
643 gclog_or_tty->print(" ");
644 gclog_or_tty->stamp();
645 gclog_or_tty->print(": ms_collection_begin ");
646 }
647 _STW_timer.stop();
648 _latest_cms_ms_end_to_ms_start = _STW_timer.seconds();
649 if (PrintAdaptiveSizePolicy && Verbose) {
650 gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::ms_collection_begin: "
651 "mutator time %f",
652 _latest_cms_ms_end_to_ms_start);
653 }
654 avg_ms_interval()->sample(_STW_timer.seconds());
655 _STW_timer.reset();
656 _STW_timer.start();
657 }
659 void CMSAdaptiveSizePolicy::ms_collection_end(GCCause::Cause gc_cause) {
660 if (PrintAdaptiveSizePolicy && Verbose) {
661 gclog_or_tty->print(" ");
662 gclog_or_tty->stamp();
663 gclog_or_tty->print(": ms_collection_end ");
664 }
665 _STW_timer.stop();
666 if (gc_cause != GCCause::_java_lang_system_gc ||
667 UseAdaptiveSizePolicyWithSystemGC) {
668 // The MS collection is a foreground collection that does all
669 // the parts of a mostly concurrent collection.
670 //
671 // For this collection include the cost of the
672 // initial mark
673 // remark
674 // all concurrent time (scaled down by the
675 // concurrent_processor_fraction). Some
676 // may be zero if the baton was passed before
677 // it was reached.
678 // concurrent marking
679 // sweeping
680 // resetting
681 // STW after baton was passed (STW_in_foreground_in_seconds)
682 double STW_in_foreground_in_seconds = _STW_timer.seconds();
684 double latest_cms_sum_concurrent_phases_time_secs =
685 concurrent_collection_time();
686 if (PrintAdaptiveSizePolicy && Verbose) {
687 gclog_or_tty->print_cr("\nCMSAdaptiveSizePolicy::ms_collecton_end "
688 "STW_in_foreground_in_seconds %f "
689 "_latest_cms_initial_mark_start_to_end_time_secs %f "
690 "_latest_cms_remark_start_to_end_time_secs %f "
691 "latest_cms_sum_concurrent_phases_time_secs %f "
692 "_latest_cms_ms_marking_start_to_end_time_secs %f "
693 "_latest_cms_ms_end_to_ms_start %f",
694 STW_in_foreground_in_seconds,
695 _latest_cms_initial_mark_start_to_end_time_secs,
696 _latest_cms_remark_start_to_end_time_secs,
697 latest_cms_sum_concurrent_phases_time_secs,
698 _latest_cms_ms_marking_start_to_end_time_secs,
699 _latest_cms_ms_end_to_ms_start);
700 }
702 double STW_marking_in_seconds = _latest_cms_initial_mark_start_to_end_time_secs +
703 _latest_cms_remark_start_to_end_time_secs;
704 #ifndef CLOCK_GRANULARITY_TOO_LARGE
705 assert(_latest_cms_ms_marking_start_to_end_time_secs == 0.0 ||
706 latest_cms_sum_concurrent_phases_time_secs == 0.0,
707 "marking done twice?");
708 #endif
709 double ms_time_in_seconds = STW_marking_in_seconds +
710 STW_in_foreground_in_seconds +
711 _latest_cms_ms_marking_start_to_end_time_secs +
712 scaled_concurrent_collection_time();
713 avg_ms_pause()->sample(ms_time_in_seconds);
714 // Use the STW costs from the initial mark and remark plus
715 // the cost of the concurrent phase to calculate a
716 // collection cost.
717 double cost = 0.0;
718 if ((_latest_cms_ms_end_to_ms_start > 0.0) &&
719 (ms_time_in_seconds > 0.0)) {
720 double interval_in_seconds =
721 _latest_cms_ms_end_to_ms_start + ms_time_in_seconds;
723 if (PrintAdaptiveSizePolicy && Verbose) {
724 gclog_or_tty->print_cr("\n ms_time_in_seconds %f "
725 "latest_cms_sum_concurrent_phases_time_secs %f "
726 "interval_in_seconds %f",
727 ms_time_in_seconds,
728 latest_cms_sum_concurrent_phases_time_secs,
729 interval_in_seconds);
730 }
732 cost = collection_cost(ms_time_in_seconds, interval_in_seconds);
734 _avg_ms_gc_cost->sample(cost);
735 // Average this ms cost into all the other types gc costs
736 avg_major_gc_cost()->sample(cost);
738 // Sample for performance counter
739 _avg_ms_interval->sample(interval_in_seconds);
740 }
741 if (PrintAdaptiveSizePolicy && Verbose) {
742 gclog_or_tty->print("cmsAdaptiveSizePolicy::ms_collection_end: "
743 "MS gc cost: %f average: %f", cost, _avg_ms_gc_cost->average());
745 double ms_time_in_ms = ms_time_in_seconds * MILLIUNITS;
746 gclog_or_tty->print_cr(" MS pause: %f (ms) MS period %f (ms)",
747 ms_time_in_ms,
748 _latest_cms_ms_end_to_ms_start * MILLIUNITS);
749 }
750 }
752 // Consider putting this code (here to end) into a
753 // method for convenience.
754 clear_internal_time_intervals();
756 set_first_after_collection();
758 // The concurrent phases keeps track of it's own mutator interval
759 // with this timer. This allows the stop-the-world phase to
760 // be included in the mutator time so that the stop-the-world time
761 // is not double counted. Reset and start it.
762 _concurrent_timer.stop();
763 _concurrent_timer.reset();
764 _concurrent_timer.start();
766 _STW_timer.reset();
767 _STW_timer.start();
768 }
770 void CMSAdaptiveSizePolicy::clear_internal_time_intervals() {
771 _latest_cms_reset_end_to_initial_mark_start_secs = 0.0;
772 _latest_cms_initial_mark_end_to_remark_start_secs = 0.0;
773 _latest_cms_collection_end_to_collection_start_secs = 0.0;
774 _latest_cms_concurrent_marking_time_secs = 0.0;
775 _latest_cms_concurrent_precleaning_time_secs = 0.0;
776 _latest_cms_concurrent_sweeping_time_secs = 0.0;
777 _latest_cms_msc_end_to_msc_start_time_secs = 0.0;
778 _latest_cms_ms_end_to_ms_start = 0.0;
779 _latest_cms_remark_start_to_end_time_secs = 0.0;
780 _latest_cms_initial_mark_start_to_end_time_secs = 0.0;
781 _latest_cms_ms_marking_start_to_end_time_secs = 0.0;
782 }
784 void CMSAdaptiveSizePolicy::clear_generation_free_space_flags() {
785 AdaptiveSizePolicy::clear_generation_free_space_flags();
787 set_change_young_gen_for_maj_pauses(0);
788 }
790 void CMSAdaptiveSizePolicy::concurrent_phases_resume() {
791 if (PrintAdaptiveSizePolicy && Verbose) {
792 gclog_or_tty->stamp();
793 gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::concurrent_phases_resume()");
794 }
795 _concurrent_timer.start();
796 }
798 double CMSAdaptiveSizePolicy::time_since_major_gc() const {
799 _concurrent_timer.stop();
800 double time_since_cms_gc = _concurrent_timer.seconds();
801 _concurrent_timer.start();
802 _STW_timer.stop();
803 double time_since_STW_gc = _STW_timer.seconds();
804 _STW_timer.start();
806 return MIN2(time_since_cms_gc, time_since_STW_gc);
807 }
809 double CMSAdaptiveSizePolicy::major_gc_interval_average_for_decay() const {
810 double cms_interval = _avg_concurrent_interval->average();
811 double msc_interval = _avg_msc_interval->average();
812 double ms_interval = _avg_ms_interval->average();
814 return MAX3(cms_interval, msc_interval, ms_interval);
815 }
817 double CMSAdaptiveSizePolicy::cms_gc_cost() const {
818 return avg_major_gc_cost()->average();
819 }
821 void CMSAdaptiveSizePolicy::ms_collection_marking_begin() {
822 _STW_timer.stop();
823 // Start accumumlating time for the marking in the STW timer.
824 _STW_timer.reset();
825 _STW_timer.start();
826 }
828 void CMSAdaptiveSizePolicy::ms_collection_marking_end(
829 GCCause::Cause gc_cause) {
830 _STW_timer.stop();
831 if (gc_cause != GCCause::_java_lang_system_gc ||
832 UseAdaptiveSizePolicyWithSystemGC) {
833 _latest_cms_ms_marking_start_to_end_time_secs = _STW_timer.seconds();
834 if (PrintAdaptiveSizePolicy && Verbose) {
835 gclog_or_tty->print_cr("CMSAdaptiveSizePolicy::"
836 "msc_collection_marking_end: mutator time %f",
837 _latest_cms_ms_marking_start_to_end_time_secs);
838 }
839 }
840 _STW_timer.reset();
841 _STW_timer.start();
842 }
844 double CMSAdaptiveSizePolicy::gc_cost() const {
845 double cms_gen_cost = cms_gc_cost();
846 double result = MIN2(1.0, minor_gc_cost() + cms_gen_cost);
847 assert(result >= 0.0, "Both minor and major costs are non-negative");
848 return result;
849 }
851 // Cost of collection (unit-less)
852 double CMSAdaptiveSizePolicy::collection_cost(double pause_in_seconds,
853 double interval_in_seconds) {
854 // Cost of collection (unit-less)
855 double cost = 0.0;
856 if ((interval_in_seconds > 0.0) &&
857 (pause_in_seconds > 0.0)) {
858 cost =
859 pause_in_seconds / interval_in_seconds;
860 }
861 return cost;
862 }
864 size_t CMSAdaptiveSizePolicy::adjust_eden_for_pause_time(size_t cur_eden) {
865 size_t change = 0;
866 size_t desired_eden = cur_eden;
868 // reduce eden size
869 change = eden_decrement_aligned_down(cur_eden);
870 desired_eden = cur_eden - change;
872 if (PrintAdaptiveSizePolicy && Verbose) {
873 gclog_or_tty->print_cr(
874 "CMSAdaptiveSizePolicy::adjust_eden_for_pause_time "
875 "adjusting eden for pause time. "
876 " starting eden size " SIZE_FORMAT
877 " reduced eden size " SIZE_FORMAT
878 " eden delta " SIZE_FORMAT,
879 cur_eden, desired_eden, change);
880 }
882 return desired_eden;
883 }
885 size_t CMSAdaptiveSizePolicy::adjust_eden_for_throughput(size_t cur_eden) {
887 size_t desired_eden = cur_eden;
889 set_change_young_gen_for_throughput(increase_young_gen_for_througput_true);
891 size_t change = eden_increment_aligned_up(cur_eden);
892 size_t scaled_change = scale_by_gen_gc_cost(change, minor_gc_cost());
894 if (cur_eden + scaled_change > cur_eden) {
895 desired_eden = cur_eden + scaled_change;
896 }
898 _young_gen_change_for_minor_throughput++;
900 if (PrintAdaptiveSizePolicy && Verbose) {
901 gclog_or_tty->print_cr(
902 "CMSAdaptiveSizePolicy::adjust_eden_for_throughput "
903 "adjusting eden for throughput. "
904 " starting eden size " SIZE_FORMAT
905 " increased eden size " SIZE_FORMAT
906 " eden delta " SIZE_FORMAT,
907 cur_eden, desired_eden, scaled_change);
908 }
910 return desired_eden;
911 }
913 size_t CMSAdaptiveSizePolicy::adjust_eden_for_footprint(size_t cur_eden) {
915 set_decrease_for_footprint(decrease_young_gen_for_footprint_true);
917 size_t change = eden_decrement(cur_eden);
918 size_t desired_eden_size = cur_eden - change;
920 if (PrintAdaptiveSizePolicy && Verbose) {
921 gclog_or_tty->print_cr(
922 "CMSAdaptiveSizePolicy::adjust_eden_for_footprint "
923 "adjusting eden for footprint. "
924 " starting eden size " SIZE_FORMAT
925 " reduced eden size " SIZE_FORMAT
926 " eden delta " SIZE_FORMAT,
927 cur_eden, desired_eden_size, change);
928 }
929 return desired_eden_size;
930 }
932 // The eden and promo versions should be combined if possible.
933 // They are the same except that the sizes of the decrement
934 // and increment are different for eden and promo.
935 size_t CMSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) {
936 size_t delta = eden_decrement(cur_eden);
937 return align_size_down(delta, generation_alignment());
938 }
940 size_t CMSAdaptiveSizePolicy::eden_increment_aligned_up(size_t cur_eden) {
941 size_t delta = eden_increment(cur_eden);
942 return align_size_up(delta, generation_alignment());
943 }
945 size_t CMSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) {
946 size_t delta = promo_decrement(cur_promo);
947 return align_size_down(delta, generation_alignment());
948 }
950 size_t CMSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) {
951 size_t delta = promo_increment(cur_promo);
952 return align_size_up(delta, generation_alignment());
953 }
956 void CMSAdaptiveSizePolicy::compute_young_generation_free_space(size_t cur_eden,
957 size_t max_eden_size)
958 {
959 size_t desired_eden_size = cur_eden;
960 size_t eden_limit = max_eden_size;
962 // Printout input
963 if (PrintGC && PrintAdaptiveSizePolicy) {
964 gclog_or_tty->print_cr(
965 "CMSAdaptiveSizePolicy::compute_young_generation_free_space: "
966 "cur_eden " SIZE_FORMAT,
967 cur_eden);
968 }
970 // Used for diagnostics
971 clear_generation_free_space_flags();
973 if (_avg_minor_pause->padded_average() > gc_pause_goal_sec()) {
974 if (minor_pause_young_estimator()->decrement_will_decrease()) {
975 // If the minor pause is too long, shrink the young gen.
976 set_change_young_gen_for_min_pauses(
977 decrease_young_gen_for_min_pauses_true);
978 desired_eden_size = adjust_eden_for_pause_time(desired_eden_size);
979 }
980 } else if ((avg_remark_pause()->padded_average() > gc_pause_goal_sec()) ||
981 (avg_initial_pause()->padded_average() > gc_pause_goal_sec())) {
982 // The remark or initial pauses are not meeting the goal. Should
983 // the generation be shrunk?
984 if (get_and_clear_first_after_collection() &&
985 ((avg_remark_pause()->padded_average() > gc_pause_goal_sec() &&
986 remark_pause_young_estimator()->decrement_will_decrease()) ||
987 (avg_initial_pause()->padded_average() > gc_pause_goal_sec() &&
988 initial_pause_young_estimator()->decrement_will_decrease()))) {
990 set_change_young_gen_for_maj_pauses(
991 decrease_young_gen_for_maj_pauses_true);
993 // If the remark or initial pause is too long and this is the
994 // first young gen collection after a cms collection, shrink
995 // the young gen.
996 desired_eden_size = adjust_eden_for_pause_time(desired_eden_size);
997 }
998 // If not the first young gen collection after a cms collection,
999 // don't do anything. In this case an adjustment has already
1000 // been made and the results of the adjustment has not yet been
1001 // measured.
1002 } else if ((minor_gc_cost() >= 0.0) &&
1003 (adjusted_mutator_cost() < _throughput_goal)) {
1004 desired_eden_size = adjust_eden_for_throughput(desired_eden_size);
1005 } else {
1006 desired_eden_size = adjust_eden_for_footprint(desired_eden_size);
1007 }
1009 if (PrintGC && PrintAdaptiveSizePolicy) {
1010 gclog_or_tty->print_cr(
1011 "CMSAdaptiveSizePolicy::compute_young_generation_free_space limits:"
1012 " desired_eden_size: " SIZE_FORMAT
1013 " old_eden_size: " SIZE_FORMAT,
1014 desired_eden_size, cur_eden);
1015 }
1017 set_eden_size(desired_eden_size);
1018 }
1020 size_t CMSAdaptiveSizePolicy::adjust_promo_for_pause_time(size_t cur_promo) {
1021 size_t change = 0;
1022 size_t desired_promo = cur_promo;
1023 // Move this test up to caller like the adjust_eden_for_pause_time()
1024 // call.
1025 if ((AdaptiveSizePausePolicy == 0) &&
1026 ((avg_remark_pause()->padded_average() > gc_pause_goal_sec()) ||
1027 (avg_initial_pause()->padded_average() > gc_pause_goal_sec()))) {
1028 set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true);
1029 change = promo_decrement_aligned_down(cur_promo);
1030 desired_promo = cur_promo - change;
1031 } else if ((AdaptiveSizePausePolicy > 0) &&
1032 (((avg_remark_pause()->padded_average() > gc_pause_goal_sec()) &&
1033 remark_pause_old_estimator()->decrement_will_decrease()) ||
1034 ((avg_initial_pause()->padded_average() > gc_pause_goal_sec()) &&
1035 initial_pause_old_estimator()->decrement_will_decrease()))) {
1036 set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true);
1037 change = promo_decrement_aligned_down(cur_promo);
1038 desired_promo = cur_promo - change;
1039 }
1041 if ((change != 0) &&PrintAdaptiveSizePolicy && Verbose) {
1042 gclog_or_tty->print_cr(
1043 "CMSAdaptiveSizePolicy::adjust_promo_for_pause_time "
1044 "adjusting promo for pause time. "
1045 " starting promo size " SIZE_FORMAT
1046 " reduced promo size " SIZE_FORMAT
1047 " promo delta " SIZE_FORMAT,
1048 cur_promo, desired_promo, change);
1049 }
1051 return desired_promo;
1052 }
1054 // Try to share this with PS.
1055 size_t CMSAdaptiveSizePolicy::scale_by_gen_gc_cost(size_t base_change,
1056 double gen_gc_cost) {
1058 // Calculate the change to use for the tenured gen.
1059 size_t scaled_change = 0;
1060 // Can the increment to the generation be scaled?
1061 if (gc_cost() >= 0.0 && gen_gc_cost >= 0.0) {
1062 double scale_by_ratio = gen_gc_cost / gc_cost();
1063 scaled_change =
1064 (size_t) (scale_by_ratio * (double) base_change);
1065 if (PrintAdaptiveSizePolicy && Verbose) {
1066 gclog_or_tty->print_cr(
1067 "Scaled tenured increment: " SIZE_FORMAT " by %f down to "
1068 SIZE_FORMAT,
1069 base_change, scale_by_ratio, scaled_change);
1070 }
1071 } else if (gen_gc_cost >= 0.0) {
1072 // Scaling is not going to work. If the major gc time is the
1073 // larger than the other GC costs, give it a full increment.
1074 if (gen_gc_cost >= (gc_cost() - gen_gc_cost)) {
1075 scaled_change = base_change;
1076 }
1077 } else {
1078 // Don't expect to get here but it's ok if it does
1079 // in the product build since the delta will be 0
1080 // and nothing will change.
1081 assert(false, "Unexpected value for gc costs");
1082 }
1084 return scaled_change;
1085 }
1087 size_t CMSAdaptiveSizePolicy::adjust_promo_for_throughput(size_t cur_promo) {
1089 size_t desired_promo = cur_promo;
1091 set_change_old_gen_for_throughput(increase_old_gen_for_throughput_true);
1093 size_t change = promo_increment_aligned_up(cur_promo);
1094 size_t scaled_change = scale_by_gen_gc_cost(change, major_gc_cost());
1096 if (cur_promo + scaled_change > cur_promo) {
1097 desired_promo = cur_promo + scaled_change;
1098 }
1100 _old_gen_change_for_major_throughput++;
1102 if (PrintAdaptiveSizePolicy && Verbose) {
1103 gclog_or_tty->print_cr(
1104 "CMSAdaptiveSizePolicy::adjust_promo_for_throughput "
1105 "adjusting promo for throughput. "
1106 " starting promo size " SIZE_FORMAT
1107 " increased promo size " SIZE_FORMAT
1108 " promo delta " SIZE_FORMAT,
1109 cur_promo, desired_promo, scaled_change);
1110 }
1112 return desired_promo;
1113 }
1115 size_t CMSAdaptiveSizePolicy::adjust_promo_for_footprint(size_t cur_promo,
1116 size_t cur_eden) {
1118 set_decrease_for_footprint(decrease_young_gen_for_footprint_true);
1120 size_t change = promo_decrement(cur_promo);
1121 size_t desired_promo_size = cur_promo - change;
1123 if (PrintAdaptiveSizePolicy && Verbose) {
1124 gclog_or_tty->print_cr(
1125 "CMSAdaptiveSizePolicy::adjust_promo_for_footprint "
1126 "adjusting promo for footprint. "
1127 " starting promo size " SIZE_FORMAT
1128 " reduced promo size " SIZE_FORMAT
1129 " promo delta " SIZE_FORMAT,
1130 cur_promo, desired_promo_size, change);
1131 }
1132 return desired_promo_size;
1133 }
1135 void CMSAdaptiveSizePolicy::compute_tenured_generation_free_space(
1136 size_t cur_tenured_free,
1137 size_t max_tenured_available,
1138 size_t cur_eden) {
1139 // This can be bad if the desired value grows/shrinks without
1140 // any connection to the read free space
1141 size_t desired_promo_size = promo_size();
1142 size_t tenured_limit = max_tenured_available;
1144 // Printout input
1145 if (PrintGC && PrintAdaptiveSizePolicy) {
1146 gclog_or_tty->print_cr(
1147 "CMSAdaptiveSizePolicy::compute_tenured_generation_free_space: "
1148 "cur_tenured_free " SIZE_FORMAT
1149 " max_tenured_available " SIZE_FORMAT,
1150 cur_tenured_free, max_tenured_available);
1151 }
1153 // Used for diagnostics
1154 clear_generation_free_space_flags();
1156 set_decide_at_full_gc(decide_at_full_gc_true);
1157 if (avg_remark_pause()->padded_average() > gc_pause_goal_sec() ||
1158 avg_initial_pause()->padded_average() > gc_pause_goal_sec()) {
1159 desired_promo_size = adjust_promo_for_pause_time(cur_tenured_free);
1160 } else if (avg_minor_pause()->padded_average() > gc_pause_goal_sec()) {
1161 // Nothing to do since the minor collections are too large and
1162 // this method only deals with the cms generation.
1163 } else if ((cms_gc_cost() >= 0.0) &&
1164 (adjusted_mutator_cost() < _throughput_goal)) {
1165 desired_promo_size = adjust_promo_for_throughput(cur_tenured_free);
1166 } else {
1167 desired_promo_size = adjust_promo_for_footprint(cur_tenured_free,
1168 cur_eden);
1169 }
1171 if (PrintGC && PrintAdaptiveSizePolicy) {
1172 gclog_or_tty->print_cr(
1173 "CMSAdaptiveSizePolicy::compute_tenured_generation_free_space limits:"
1174 " desired_promo_size: " SIZE_FORMAT
1175 " old_promo_size: " SIZE_FORMAT,
1176 desired_promo_size, cur_tenured_free);
1177 }
1179 set_promo_size(desired_promo_size);
1180 }
1182 int CMSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
1183 bool is_survivor_overflow,
1184 int tenuring_threshold,
1185 size_t survivor_limit) {
1186 assert(survivor_limit >= generation_alignment(),
1187 "survivor_limit too small");
1188 assert((size_t)align_size_down(survivor_limit, generation_alignment())
1189 == survivor_limit, "survivor_limit not aligned");
1191 // Change UsePSAdaptiveSurvivorSizePolicy -> UseAdaptiveSurvivorSizePolicy?
1192 if (!UsePSAdaptiveSurvivorSizePolicy ||
1193 !young_gen_policy_is_ready()) {
1194 return tenuring_threshold;
1195 }
1197 // We'll decide whether to increase or decrease the tenuring
1198 // threshold based partly on the newly computed survivor size
1199 // (if we hit the maximum limit allowed, we'll always choose to
1200 // decrement the threshold).
1201 bool incr_tenuring_threshold = false;
1202 bool decr_tenuring_threshold = false;
1204 set_decrement_tenuring_threshold_for_gc_cost(false);
1205 set_increment_tenuring_threshold_for_gc_cost(false);
1206 set_decrement_tenuring_threshold_for_survivor_limit(false);
1208 if (!is_survivor_overflow) {
1209 // Keep running averages on how much survived
1211 // We use the tenuring threshold to equalize the cost of major
1212 // and minor collections.
1213 // ThresholdTolerance is used to indicate how sensitive the
1214 // tenuring threshold is to differences in cost betweent the
1215 // collection types.
1217 // Get the times of interest. This involves a little work, so
1218 // we cache the values here.
1219 const double major_cost = major_gc_cost();
1220 const double minor_cost = minor_gc_cost();
1222 if (minor_cost > major_cost * _threshold_tolerance_percent) {
1223 // Minor times are getting too long; lower the threshold so
1224 // less survives and more is promoted.
1225 decr_tenuring_threshold = true;
1226 set_decrement_tenuring_threshold_for_gc_cost(true);
1227 } else if (major_cost > minor_cost * _threshold_tolerance_percent) {
1228 // Major times are too long, so we want less promotion.
1229 incr_tenuring_threshold = true;
1230 set_increment_tenuring_threshold_for_gc_cost(true);
1231 }
1233 } else {
1234 // Survivor space overflow occurred, so promoted and survived are
1235 // not accurate. We'll make our best guess by combining survived
1236 // and promoted and count them as survivors.
1237 //
1238 // We'll lower the tenuring threshold to see if we can correct
1239 // things. Also, set the survivor size conservatively. We're
1240 // trying to avoid many overflows from occurring if defnew size
1241 // is just too small.
1243 decr_tenuring_threshold = true;
1244 }
1246 // The padded average also maintains a deviation from the average;
1247 // we use this to see how good of an estimate we have of what survived.
1248 // We're trying to pad the survivor size as little as possible without
1249 // overflowing the survivor spaces.
1250 size_t target_size = align_size_up((size_t)_avg_survived->padded_average(),
1251 generation_alignment());
1252 target_size = MAX2(target_size, generation_alignment());
1254 if (target_size > survivor_limit) {
1255 // Target size is bigger than we can handle. Let's also reduce
1256 // the tenuring threshold.
1257 target_size = survivor_limit;
1258 decr_tenuring_threshold = true;
1259 set_decrement_tenuring_threshold_for_survivor_limit(true);
1260 }
1262 // Finally, increment or decrement the tenuring threshold, as decided above.
1263 // We test for decrementing first, as we might have hit the target size
1264 // limit.
1265 if (decr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
1266 if (tenuring_threshold > 1) {
1267 tenuring_threshold--;
1268 }
1269 } else if (incr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
1270 if (tenuring_threshold < MaxTenuringThreshold) {
1271 tenuring_threshold++;
1272 }
1273 }
1275 // We keep a running average of the amount promoted which is used
1276 // to decide when we should collect the old generation (when
1277 // the amount of old gen free space is less than what we expect to
1278 // promote).
1280 if (PrintAdaptiveSizePolicy) {
1281 // A little more detail if Verbose is on
1282 GenCollectedHeap* gch = GenCollectedHeap::heap();
1283 if (Verbose) {
1284 gclog_or_tty->print( " avg_survived: %f"
1285 " avg_deviation: %f",
1286 _avg_survived->average(),
1287 _avg_survived->deviation());
1288 }
1290 gclog_or_tty->print( " avg_survived_padded_avg: %f",
1291 _avg_survived->padded_average());
1293 if (Verbose) {
1294 gclog_or_tty->print( " avg_promoted_avg: %f"
1295 " avg_promoted_dev: %f",
1296 gch->gc_stats(1)->avg_promoted()->average(),
1297 gch->gc_stats(1)->avg_promoted()->deviation());
1298 }
1300 gclog_or_tty->print( " avg_promoted_padded_avg: %f"
1301 " avg_pretenured_padded_avg: %f"
1302 " tenuring_thresh: %d"
1303 " target_size: " SIZE_FORMAT
1304 " survivor_limit: " SIZE_FORMAT,
1305 gch->gc_stats(1)->avg_promoted()->padded_average(),
1306 _avg_pretenured->padded_average(),
1307 tenuring_threshold, target_size, survivor_limit);
1308 gclog_or_tty->cr();
1309 }
1311 set_survivor_size(target_size);
1313 return tenuring_threshold;
1314 }
1316 bool CMSAdaptiveSizePolicy::get_and_clear_first_after_collection() {
1317 bool result = _first_after_collection;
1318 _first_after_collection = false;
1319 return result;
1320 }
1322 bool CMSAdaptiveSizePolicy::print_adaptive_size_policy_on(
1323 outputStream* st) const {
1325 if (!UseAdaptiveSizePolicy) return false;
1327 GenCollectedHeap* gch = GenCollectedHeap::heap();
1328 Generation* gen0 = gch->get_gen(0);
1329 DefNewGeneration* def_new = gen0->as_DefNewGeneration();
1330 return
1331 AdaptiveSizePolicy::print_adaptive_size_policy_on(
1332 st,
1333 def_new->tenuring_threshold());
1334 }