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 = |
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) { |