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