comparison src/share/vm/memory/collectorPolicy.cpp @ 13:183f41cf8bfe

6557851: CMS: ergonomics defaults are not set with FLAG_SET_ERGO Summary: Default values set by cms ergonomics are set with FLAG_SET_DEFAULT so down stream the values look like the default values and affect how later parameters are set. Set these values with FLAG_SET_ERGO instead and adjust how later parameters are interpreted. Reviewed-by: iveresov, apetrusenko, pbk, ysr
author jmasa
date Sun, 02 Mar 2008 16:10:12 -0800
parents a61af66fc99e
children d1605aabd0a1 37f87013dfd8
comparison
equal deleted inserted replaced
12:6432c3bb6240 13:183f41cf8bfe
55 55
56 void CollectorPolicy::initialize_size_info() { 56 void CollectorPolicy::initialize_size_info() {
57 // User inputs from -mx and ms are aligned 57 // User inputs from -mx and ms are aligned
58 _initial_heap_byte_size = align_size_up(Arguments::initial_heap_size(), 58 _initial_heap_byte_size = align_size_up(Arguments::initial_heap_size(),
59 min_alignment()); 59 min_alignment());
60 _min_heap_byte_size = align_size_up(Arguments::min_heap_size(), 60 set_min_heap_byte_size(align_size_up(Arguments::min_heap_size(),
61 min_alignment()); 61 min_alignment()));
62 _max_heap_byte_size = align_size_up(MaxHeapSize, max_alignment()); 62 set_max_heap_byte_size(align_size_up(MaxHeapSize, max_alignment()));
63 63
64 // Check validity of heap parameters from launcher 64 // Check validity of heap parameters from launcher
65 if (_initial_heap_byte_size == 0) { 65 if (initial_heap_byte_size() == 0) {
66 _initial_heap_byte_size = NewSize + OldSize; 66 set_initial_heap_byte_size(NewSize + OldSize);
67 } else { 67 } else {
68 Universe::check_alignment(_initial_heap_byte_size, min_alignment(), 68 Universe::check_alignment(initial_heap_byte_size(), min_alignment(),
69 "initial heap"); 69 "initial heap");
70 } 70 }
71 if (_min_heap_byte_size == 0) { 71 if (min_heap_byte_size() == 0) {
72 _min_heap_byte_size = NewSize + OldSize; 72 set_min_heap_byte_size(NewSize + OldSize);
73 } else { 73 } else {
74 Universe::check_alignment(_min_heap_byte_size, min_alignment(), 74 Universe::check_alignment(min_heap_byte_size(), min_alignment(),
75 "initial heap"); 75 "initial heap");
76 } 76 }
77 77
78 // Check heap parameter properties 78 // Check heap parameter properties
79 if (_initial_heap_byte_size < M) { 79 if (initial_heap_byte_size() < M) {
80 vm_exit_during_initialization("Too small initial heap"); 80 vm_exit_during_initialization("Too small initial heap");
81 } 81 }
82 // Check heap parameter properties 82 // Check heap parameter properties
83 if (_min_heap_byte_size < M) { 83 if (min_heap_byte_size() < M) {
84 vm_exit_during_initialization("Too small minimum heap"); 84 vm_exit_during_initialization("Too small minimum heap");
85 } 85 }
86 if (_initial_heap_byte_size <= NewSize) { 86 if (initial_heap_byte_size() <= NewSize) {
87 // make sure there is at least some room in old space 87 // make sure there is at least some room in old space
88 vm_exit_during_initialization("Too small initial heap for new size specified"); 88 vm_exit_during_initialization("Too small initial heap for new size specified");
89 } 89 }
90 if (_max_heap_byte_size < _min_heap_byte_size) { 90 if (max_heap_byte_size() < min_heap_byte_size()) {
91 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified"); 91 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
92 } 92 }
93 if (_initial_heap_byte_size < _min_heap_byte_size) { 93 if (initial_heap_byte_size() < min_heap_byte_size()) {
94 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified"); 94 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
95 } 95 }
96 if (_max_heap_byte_size < _initial_heap_byte_size) { 96 if (max_heap_byte_size() < initial_heap_byte_size()) {
97 vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); 97 vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
98 }
99
100 if (PrintGCDetails && Verbose) {
101 gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
102 SIZE_FORMAT " Maximum heap " SIZE_FORMAT,
103 min_heap_byte_size(), initial_heap_byte_size(), max_heap_byte_size());
98 } 104 }
99 } 105 }
100 106
101 void CollectorPolicy::initialize_perm_generation(PermGen::Name pgnm) { 107 void CollectorPolicy::initialize_perm_generation(PermGen::Name pgnm) {
102 _permanent_generation = 108 _permanent_generation =
126 } 132 }
127 } 133 }
128 134
129 // GenCollectorPolicy methods. 135 // GenCollectorPolicy methods.
130 136
137 size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
138 size_t x = base_size / (NewRatio+1);
139 size_t new_gen_size = x > min_alignment() ?
140 align_size_down(x, min_alignment()) :
141 min_alignment();
142 return new_gen_size;
143 }
144
145 size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
146 size_t maximum_size) {
147 size_t alignment = min_alignment();
148 size_t max_minus = maximum_size - alignment;
149 return desired_size < max_minus ? desired_size : max_minus;
150 }
151
152
131 void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, 153 void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
132 size_t init_promo_size, 154 size_t init_promo_size,
133 size_t init_survivor_size) { 155 size_t init_survivor_size) {
134 double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; 156 const double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
135 _size_policy = new AdaptiveSizePolicy(init_eden_size, 157 _size_policy = new AdaptiveSizePolicy(init_eden_size,
136 init_promo_size, 158 init_promo_size,
137 init_survivor_size, 159 init_survivor_size,
138 max_gc_minor_pause_sec, 160 max_gc_minor_pause_sec,
139 GCTimeRatio); 161 GCTimeRatio);
208 // Check validity of heap flags 230 // Check validity of heap flags
209 assert(OldSize % min_alignment() == 0, "old space alignment"); 231 assert(OldSize % min_alignment() == 0, "old space alignment");
210 assert(MaxHeapSize % max_alignment() == 0, "maximum heap alignment"); 232 assert(MaxHeapSize % max_alignment() == 0, "maximum heap alignment");
211 } 233 }
212 234
235 // Values set on the command line win over any ergonomically
236 // set command line parameters.
237 // Ergonomic choice of parameters are done before this
238 // method is called. Values for command line parameters such as NewSize
239 // and MaxNewSize feed those ergonomic choices into this method.
240 // This method makes the final generation sizings consistent with
241 // themselves and with overall heap sizings.
242 // In the absence of explicitly set command line flags, policies
243 // such as the use of NewRatio are used to size the generation.
213 void GenCollectorPolicy::initialize_size_info() { 244 void GenCollectorPolicy::initialize_size_info() {
214 CollectorPolicy::initialize_size_info(); 245 CollectorPolicy::initialize_size_info();
215 246
216 // Minimum sizes of the generations may be different than 247 // min_alignment() is used for alignment within a generation.
217 // the initial sizes. 248 // There is additional alignment done down stream for some
218 if (!FLAG_IS_DEFAULT(NewSize)) { 249 // collectors that sometimes causes unwanted rounding up of
219 _min_gen0_size = NewSize; 250 // generations sizes.
251
252 // Determine maximum size of gen0
253
254 size_t max_new_size = 0;
255 if (FLAG_IS_CMDLINE(MaxNewSize)) {
256 if (MaxNewSize < min_alignment()) {
257 max_new_size = min_alignment();
258 } else if (MaxNewSize >= max_heap_byte_size()) {
259 max_new_size = align_size_down(max_heap_byte_size() - min_alignment(),
260 min_alignment());
261 warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or "
262 "greater than the entire heap (" SIZE_FORMAT "k). A "
263 "new generation size of " SIZE_FORMAT "k will be used.",
264 MaxNewSize/K, max_heap_byte_size()/K, max_new_size/K);
265 } else {
266 max_new_size = align_size_down(MaxNewSize, min_alignment());
267 }
268
269 // The case for FLAG_IS_ERGO(MaxNewSize) could be treated
270 // specially at this point to just use an ergonomically set
271 // MaxNewSize to set max_new_size. For cases with small
272 // heaps such a policy often did not work because the MaxNewSize
273 // was larger than the entire heap. The interpretation given
274 // to ergonomically set flags is that the flags are set
275 // by different collectors for their own special needs but
276 // are not allowed to badly shape the heap. This allows the
277 // different collectors to decide what's best for themselves
278 // without having to factor in the overall heap shape. It
279 // can be the case in the future that the collectors would
280 // only make "wise" ergonomics choices and this policy could
281 // just accept those choices. The choices currently made are
282 // not always "wise".
220 } else { 283 } else {
221 _min_gen0_size = align_size_down(_min_heap_byte_size / (NewRatio+1), 284 max_new_size = scale_by_NewRatio_aligned(max_heap_byte_size());
222 min_alignment()); 285 // Bound the maximum size by NewSize below (since it historically
223 // We bound the minimum size by NewSize below (since it historically
224 // would have been NewSize and because the NewRatio calculation could 286 // would have been NewSize and because the NewRatio calculation could
225 // yield a size that is too small) and bound it by MaxNewSize above. 287 // yield a size that is too small) and bound it by MaxNewSize above.
226 // This is not always best. The NewSize calculated by CMS (which has 288 // Ergonomics plays here by previously calculating the desired
227 // a fixed minimum of 16m) can sometimes be "too" large. Consider 289 // NewSize and MaxNewSize.
228 // the case where -Xmx32m. The CMS calculated NewSize would be about 290 max_new_size = MIN2(MAX2(max_new_size, NewSize), MaxNewSize);
229 // half the entire heap which seems too large. But the counter 291 }
230 // example is seen when the client defaults for NewRatio are used. 292 assert(max_new_size > 0, "All paths should set max_new_size");
231 // An initial young generation size of 640k was observed 293
232 // with -Xmx128m -XX:MaxNewSize=32m when NewSize was not used 294 // Given the maximum gen0 size, determine the initial and
233 // as a lower bound as with 295 // minimum sizes.
234 // _min_gen0_size = MIN2(_min_gen0_size, MaxNewSize); 296
235 // and 640k seemed too small a young generation. 297 if (max_heap_byte_size() == min_heap_byte_size()) {
236 _min_gen0_size = MIN2(MAX2(_min_gen0_size, NewSize), MaxNewSize); 298 // The maximum and minimum heap sizes are the same so
237 } 299 // the generations minimum and initial must be the
238 300 // same as its maximum.
239 // Parameters are valid, compute area sizes. 301 set_min_gen0_size(max_new_size);
240 size_t max_new_size = align_size_down(_max_heap_byte_size / (NewRatio+1), 302 set_initial_gen0_size(max_new_size);
241 min_alignment()); 303 set_max_gen0_size(max_new_size);
242 max_new_size = MIN2(MAX2(max_new_size, _min_gen0_size), MaxNewSize); 304 } else {
243 305 size_t desired_new_size = 0;
244 // desired_new_size is used to set the initial size. The 306 if (!FLAG_IS_DEFAULT(NewSize)) {
245 // initial size must be greater than the minimum size. 307 // If NewSize is set ergonomically (for example by cms), it
246 size_t desired_new_size = 308 // would make sense to use it. If it is used, also use it
247 align_size_down(_initial_heap_byte_size / (NewRatio+1), 309 // to set the initial size. Although there is no reason
248 min_alignment()); 310 // the minimum size and the initial size have to be the same,
249 311 // the current implementation gets into trouble during the calculation
250 size_t new_size = MIN2(MAX2(desired_new_size, _min_gen0_size), max_new_size); 312 // of the tenured generation sizes if they are different.
251 313 // Note that this makes the initial size and the minimum size
252 _initial_gen0_size = new_size; 314 // generally small compared to the NewRatio calculation.
253 _max_gen0_size = max_new_size; 315 _min_gen0_size = NewSize;
254 } 316 desired_new_size = NewSize;
317 max_new_size = MAX2(max_new_size, NewSize);
318 } else {
319 // For the case where NewSize is the default, use NewRatio
320 // to size the minimum and initial generation sizes.
321 // Use the default NewSize as the floor for these values. If
322 // NewRatio is overly large, the resulting sizes can be too
323 // small.
324 _min_gen0_size = MAX2(scale_by_NewRatio_aligned(min_heap_byte_size()),
325 NewSize);
326 desired_new_size =
327 MAX2(scale_by_NewRatio_aligned(initial_heap_byte_size()),
328 NewSize);
329 }
330
331 assert(_min_gen0_size > 0, "Sanity check");
332 set_initial_gen0_size(desired_new_size);
333 set_max_gen0_size(max_new_size);
334
335 // At this point the desirable initial and minimum sizes have been
336 // determined without regard to the maximum sizes.
337
338 // Bound the sizes by the corresponding overall heap sizes.
339 set_min_gen0_size(
340 bound_minus_alignment(_min_gen0_size, min_heap_byte_size()));
341 set_initial_gen0_size(
342 bound_minus_alignment(_initial_gen0_size, initial_heap_byte_size()));
343 set_max_gen0_size(
344 bound_minus_alignment(_max_gen0_size, max_heap_byte_size()));
345
346 // At this point all three sizes have been checked against the
347 // maximum sizes but have not been checked for consistency
348 // amoung the three.
349
350 // Final check min <= initial <= max
351 set_min_gen0_size(MIN2(_min_gen0_size, _max_gen0_size));
352 set_initial_gen0_size(
353 MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size));
354 set_min_gen0_size(MIN2(_min_gen0_size, _initial_gen0_size));
355 }
356
357 if (PrintGCDetails && Verbose) {
358 gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 "
359 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
360 min_gen0_size(), initial_gen0_size(), max_gen0_size());
361 }
362 }
363
364 // Call this method during the sizing of the gen1 to make
365 // adjustments to gen0 because of gen1 sizing policy. gen0 initially has
366 // the most freedom in sizing because it is done before the
367 // policy for gen1 is applied. Once gen1 policies have been applied,
368 // there may be conflicts in the shape of the heap and this method
369 // is used to make the needed adjustments. The application of the
370 // policies could be more sophisticated (iterative for example) but
371 // keeping it simple also seems a worthwhile goal.
372 bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr,
373 size_t* gen1_size_ptr,
374 size_t heap_size,
375 size_t min_gen0_size) {
376 bool result = false;
377 if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) {
378 if (((*gen0_size_ptr + OldSize) > heap_size) &&
379 (heap_size - min_gen0_size) >= min_alignment()) {
380 // Adjust gen0 down to accomodate OldSize
381 *gen0_size_ptr = heap_size - min_gen0_size;
382 *gen0_size_ptr =
383 MAX2((uintx)align_size_down(*gen0_size_ptr, min_alignment()),
384 min_alignment());
385 assert(*gen0_size_ptr > 0, "Min gen0 is too large");
386 result = true;
387 } else {
388 *gen1_size_ptr = heap_size - *gen0_size_ptr;
389 *gen1_size_ptr =
390 MAX2((uintx)align_size_down(*gen1_size_ptr, min_alignment()),
391 min_alignment());
392 }
393 }
394 return result;
395 }
396
397 // Minimum sizes of the generations may be different than
398 // the initial sizes. An inconsistently is permitted here
399 // in the total size that can be specified explicitly by
400 // command line specification of OldSize and NewSize and
401 // also a command line specification of -Xms. Issue a warning
402 // but allow the values to pass.
255 403
256 void TwoGenerationCollectorPolicy::initialize_size_info() { 404 void TwoGenerationCollectorPolicy::initialize_size_info() {
257 GenCollectorPolicy::initialize_size_info(); 405 GenCollectorPolicy::initialize_size_info();
258 406
259 // Minimum sizes of the generations may be different than 407 // At this point the minimum, initial and maximum sizes
260 // the initial sizes. An inconsistently is permitted here 408 // of the overall heap and of gen0 have been determined.
261 // in the total size that can be specified explicitly by 409 // The maximum gen1 size can be determined from the maximum gen0
262 // command line specification of OldSize and NewSize and 410 // and maximum heap size since not explicit flags exits
263 // also a command line specification of -Xms. Issue a warning 411 // for setting the gen1 maximum.
264 // but allow the values to pass. 412 _max_gen1_size = max_heap_byte_size() - _max_gen0_size;
265 if (!FLAG_IS_DEFAULT(OldSize)) { 413 _max_gen1_size =
266 _min_gen1_size = OldSize; 414 MAX2((uintx)align_size_down(_max_gen1_size, min_alignment()),
415 min_alignment());
416 // If no explicit command line flag has been set for the
417 // gen1 size, use what is left for gen1.
418 if (FLAG_IS_DEFAULT(OldSize) || FLAG_IS_ERGO(OldSize)) {
419 // The user has not specified any value or ergonomics
420 // has chosen a value (which may or may not be consistent
421 // with the overall heap size). In either case make
422 // the minimum, maximum and initial sizes consistent
423 // with the gen0 sizes and the overall heap sizes.
424 assert(min_heap_byte_size() > _min_gen0_size,
425 "gen0 has an unexpected minimum size");
426 set_min_gen1_size(min_heap_byte_size() - min_gen0_size());
427 set_min_gen1_size(
428 MAX2((uintx)align_size_down(_min_gen1_size, min_alignment()),
429 min_alignment()));
430 set_initial_gen1_size(initial_heap_byte_size() - initial_gen0_size());
431 set_initial_gen1_size(
432 MAX2((uintx)align_size_down(_initial_gen1_size, min_alignment()),
433 min_alignment()));
434
435 } else {
436 // It's been explicitly set on the command line. Use the
437 // OldSize and then determine the consequences.
438 set_min_gen1_size(OldSize);
439 set_initial_gen1_size(OldSize);
440
441 // If the user has explicitly set an OldSize that is inconsistent
442 // with other command line flags, issue a warning.
267 // The generation minimums and the overall heap mimimum should 443 // The generation minimums and the overall heap mimimum should
268 // be within one heap alignment. 444 // be within one heap alignment.
269 if ((_min_gen1_size + _min_gen0_size + max_alignment()) < 445 if ((_min_gen1_size + _min_gen0_size + min_alignment()) <
270 _min_heap_byte_size) { 446 min_heap_byte_size()) {
271 warning("Inconsistency between minimum heap size and minimum " 447 warning("Inconsistency between minimum heap size and minimum "
272 "generation sizes: using min heap = " SIZE_FORMAT, 448 "generation sizes: using minimum heap = " SIZE_FORMAT,
273 _min_heap_byte_size); 449 min_heap_byte_size());
274 } 450 }
275 } else { 451 if ((OldSize > _max_gen1_size)) {
276 _min_gen1_size = _min_heap_byte_size - _min_gen0_size; 452 warning("Inconsistency between maximum heap size and maximum "
277 } 453 "generation sizes: using maximum heap = " SIZE_FORMAT
278 454 " -XX:OldSize flag is being ignored",
279 _initial_gen1_size = _initial_heap_byte_size - _initial_gen0_size; 455 max_heap_byte_size());
280 _max_gen1_size = _max_heap_byte_size - _max_gen0_size; 456 }
457 // If there is an inconsistency between the OldSize and the minimum and/or
458 // initial size of gen0, since OldSize was explicitly set, OldSize wins.
459 if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
460 min_heap_byte_size(), OldSize)) {
461 if (PrintGCDetails && Verbose) {
462 gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 "
463 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
464 min_gen0_size(), initial_gen0_size(), max_gen0_size());
465 }
466 }
467 // Initial size
468 if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
469 initial_heap_byte_size(), OldSize)) {
470 if (PrintGCDetails && Verbose) {
471 gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT " Initial gen0 "
472 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
473 min_gen0_size(), initial_gen0_size(), max_gen0_size());
474 }
475 }
476 }
477 // Enforce the maximum gen1 size.
478 set_min_gen1_size(MIN2(_min_gen1_size, _max_gen1_size));
479
480 // Check that min gen1 <= initial gen1 <= max gen1
481 set_initial_gen1_size(MAX2(_initial_gen1_size, _min_gen1_size));
482 set_initial_gen1_size(MIN2(_initial_gen1_size, _max_gen1_size));
483
484 if (PrintGCDetails && Verbose) {
485 gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 "
486 SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT,
487 min_gen1_size(), initial_gen1_size(), max_gen1_size());
488 }
281 } 489 }
282 490
283 HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, 491 HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
284 bool is_tlab, 492 bool is_tlab,
285 bool* gc_overhead_limit_was_exceeded) { 493 bool* gc_overhead_limit_was_exceeded) {