33 #include "gc/shared/space.hpp"
34 #include "gc/shared/vmGCOperations.hpp"
35 #include "logging/log.hpp"
36 #include "memory/universe.hpp"
37 #include "runtime/arguments.hpp"
38 #include "runtime/globals_extension.hpp"
39 #include "runtime/handles.inline.hpp"
40 #include "runtime/java.hpp"
41 #include "runtime/thread.inline.hpp"
42 #include "runtime/vmThread.hpp"
43 #include "utilities/macros.hpp"
44
45 // CollectorPolicy methods
46
47 CollectorPolicy::CollectorPolicy() :
48 _space_alignment(0),
49 _heap_alignment(0),
50 _initial_heap_byte_size(InitialHeapSize),
51 _max_heap_byte_size(MaxHeapSize),
52 _min_heap_byte_size(Arguments::min_heap_size()),
53 _max_heap_size_cmdline(false),
54 _size_policy(NULL),
55 _should_clear_all_soft_refs(false),
56 _all_soft_refs_clear(false)
57 {}
58
59 #ifdef ASSERT
60 void CollectorPolicy::assert_flags() {
61 assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes");
62 assert(InitialHeapSize % _heap_alignment == 0, "InitialHeapSize alignment");
63 assert(MaxHeapSize % _heap_alignment == 0, "MaxHeapSize alignment");
64 }
65
66 void CollectorPolicy::assert_size_info() {
67 assert(InitialHeapSize == _initial_heap_byte_size, "Discrepancy between InitialHeapSize flag and local storage");
68 assert(MaxHeapSize == _max_heap_byte_size, "Discrepancy between MaxHeapSize flag and local storage");
69 assert(_max_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible minimum and maximum heap sizes");
70 assert(_initial_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible initial and minimum heap sizes");
71 assert(_max_heap_byte_size >= _initial_heap_byte_size, "Ergonomics decided on incompatible initial and maximum heap sizes");
72 assert(_min_heap_byte_size % _heap_alignment == 0, "min_heap_byte_size alignment");
73 assert(_initial_heap_byte_size % _heap_alignment == 0, "initial_heap_byte_size alignment");
75 }
76 #endif // ASSERT
77
78 void CollectorPolicy::initialize_flags() {
79 assert(_space_alignment != 0, "Space alignment not set up properly");
80 assert(_heap_alignment != 0, "Heap alignment not set up properly");
81 assert(_heap_alignment >= _space_alignment,
82 "heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,
83 _heap_alignment, _space_alignment);
84 assert(_heap_alignment % _space_alignment == 0,
85 "heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
86 _heap_alignment, _space_alignment);
87
88 if (FLAG_IS_CMDLINE(MaxHeapSize)) {
89 if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
90 vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size");
91 }
92 if (_min_heap_byte_size != 0 && MaxHeapSize < _min_heap_byte_size) {
93 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
94 }
95 _max_heap_size_cmdline = true;
96 }
97
98 // Check heap parameter properties
99 if (MaxHeapSize < 2 * M) {
100 vm_exit_during_initialization("Too small maximum heap");
101 }
102 if (InitialHeapSize < M) {
103 vm_exit_during_initialization("Too small initial heap");
104 }
105 if (_min_heap_byte_size < M) {
106 vm_exit_during_initialization("Too small minimum heap");
107 }
108
109 // User inputs from -Xmx and -Xms must be aligned
110 _min_heap_byte_size = align_size_up(_min_heap_byte_size, _heap_alignment);
111 size_t aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
112 size_t aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
113
114 // Write back to flags if the values changed
115 if (aligned_initial_heap_size != InitialHeapSize) {
268 assert(_min_young_size + _min_old_size <= _min_heap_byte_size, "Minimum generation sizes exceed minimum heap size");
269 assert(_initial_young_size + _initial_old_size == _initial_heap_byte_size, "Initial generation sizes should match initial heap size");
270 assert(_max_young_size + _max_old_size == _max_heap_byte_size, "Maximum generation sizes should match maximum heap size");
271 }
272 #endif // ASSERT
273
274 void GenCollectorPolicy::initialize_flags() {
275 CollectorPolicy::initialize_flags();
276
277 assert(_gen_alignment != 0, "Generation alignment not set up properly");
278 assert(_heap_alignment >= _gen_alignment,
279 "heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT,
280 _heap_alignment, _gen_alignment);
281 assert(_gen_alignment % _space_alignment == 0,
282 "gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
283 _gen_alignment, _space_alignment);
284 assert(_heap_alignment % _gen_alignment == 0,
285 "heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT,
286 _heap_alignment, _gen_alignment);
287
288 // All generational heaps have a youngest gen; handle those flags here
289
290 // Make sure the heap is large enough for two generations
291 size_t smallest_new_size = young_gen_size_lower_bound();
292 size_t smallest_heap_size = align_size_up(smallest_new_size + old_gen_size_lower_bound(),
293 _heap_alignment);
294 if (MaxHeapSize < smallest_heap_size) {
295 FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size);
296 _max_heap_byte_size = MaxHeapSize;
297 }
298 // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size
299 if (_min_heap_byte_size < smallest_heap_size) {
300 _min_heap_byte_size = smallest_heap_size;
301 if (InitialHeapSize < _min_heap_byte_size) {
302 FLAG_SET_ERGO(size_t, InitialHeapSize, smallest_heap_size);
303 _initial_heap_byte_size = smallest_heap_size;
304 }
305 }
306
307 // Make sure NewSize allows an old generation to fit even if set on the command line
308 if (FLAG_IS_CMDLINE(NewSize) && NewSize >= _initial_heap_byte_size) {
309 log_warning(gc, ergo)("NewSize was set larger than initial heap size, will use initial heap size.");
310 NewSize = bound_minus_alignment(NewSize, _initial_heap_byte_size);
311 }
312
313 // Now take the actual NewSize into account. We will silently increase NewSize
314 // if the user specified a smaller or unaligned value.
315 size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize);
316 bounded_new_size = MAX2(smallest_new_size, (size_t)align_size_down(bounded_new_size, _gen_alignment));
317 if (bounded_new_size != NewSize) {
318 // Do not use FLAG_SET_ERGO to update NewSize here, since this will override
319 // if NewSize was set on the command line or not. This information is needed
320 // later when setting the initial and minimum young generation size.
321 NewSize = bounded_new_size;
322 }
323 _min_young_size = smallest_new_size;
324 _initial_young_size = NewSize;
325
326 if (!FLAG_IS_DEFAULT(MaxNewSize)) {
327 if (MaxNewSize >= MaxHeapSize) {
328 // Make sure there is room for an old generation
329 size_t smaller_max_new_size = MaxHeapSize - _gen_alignment;
330 if (FLAG_IS_CMDLINE(MaxNewSize)) {
331 log_warning(gc, ergo)("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "
332 "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.",
333 MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
334 }
335 FLAG_SET_ERGO(size_t, MaxNewSize, smaller_max_new_size);
336 if (NewSize > MaxNewSize) {
337 FLAG_SET_ERGO(size_t, NewSize, MaxNewSize);
338 _initial_young_size = NewSize;
339 }
340 } else if (MaxNewSize < _initial_young_size) {
341 FLAG_SET_ERGO(size_t, MaxNewSize, _initial_young_size);
344 }
345 _max_young_size = MaxNewSize;
346 }
347
348 if (NewSize > MaxNewSize) {
349 // At this point this should only happen if the user specifies a large NewSize and/or
350 // a small (but not too small) MaxNewSize.
351 if (FLAG_IS_CMDLINE(MaxNewSize)) {
352 log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
353 "A new max generation size of " SIZE_FORMAT "k will be used.",
354 NewSize/K, MaxNewSize/K, NewSize/K);
355 }
356 FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
357 _max_young_size = MaxNewSize;
358 }
359
360 if (SurvivorRatio < 1 || NewRatio < 1) {
361 vm_exit_during_initialization("Invalid young gen ratio specified");
362 }
363
364 OldSize = MAX2(OldSize, old_gen_size_lower_bound());
365 if (!is_size_aligned(OldSize, _gen_alignment)) {
366 // Setting OldSize directly to preserve information about the possible
367 // setting of OldSize on the command line.
368 OldSize = align_size_down(OldSize, _gen_alignment);
369 }
370
371 if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {
372 // NewRatio will be used later to set the young generation size so we use
373 // it to calculate how big the heap should be based on the requested OldSize
374 // and NewRatio.
375 assert(NewRatio > 0, "NewRatio should have been set up earlier");
376 size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
377
378 calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment);
379 FLAG_SET_ERGO(size_t, MaxHeapSize, calculated_heapsize);
380 _max_heap_byte_size = MaxHeapSize;
381 FLAG_SET_ERGO(size_t, InitialHeapSize, calculated_heapsize);
382 _initial_heap_byte_size = InitialHeapSize;
383 }
384
385 // Adjust NewSize and OldSize or MaxHeapSize to match each other
386 if (NewSize + OldSize > MaxHeapSize) {
387 if (_max_heap_size_cmdline) {
388 // Somebody has set a maximum heap size with the intention that we should not
389 // exceed it. Adjust New/OldSize as necessary.
390 size_t calculated_size = NewSize + OldSize;
391 double shrink_factor = (double) MaxHeapSize / calculated_size;
392 size_t smaller_new_size = align_size_down((size_t)(NewSize * shrink_factor), _gen_alignment);
393 FLAG_SET_ERGO(size_t, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
394 _initial_young_size = NewSize;
395
396 // OldSize is already aligned because above we aligned MaxHeapSize to
397 // _heap_alignment, and we just made sure that NewSize is aligned to
398 // _gen_alignment. In initialize_flags() we verified that _heap_alignment
399 // is a multiple of _gen_alignment.
400 FLAG_SET_ERGO(size_t, OldSize, MaxHeapSize - NewSize);
401 } else {
402 FLAG_SET_ERGO(size_t, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
403 _max_heap_byte_size = MaxHeapSize;
404 }
405 }
406
407 // Update NewSize, if possible, to avoid sizing the young gen too small when only
|
33 #include "gc/shared/space.hpp"
34 #include "gc/shared/vmGCOperations.hpp"
35 #include "logging/log.hpp"
36 #include "memory/universe.hpp"
37 #include "runtime/arguments.hpp"
38 #include "runtime/globals_extension.hpp"
39 #include "runtime/handles.inline.hpp"
40 #include "runtime/java.hpp"
41 #include "runtime/thread.inline.hpp"
42 #include "runtime/vmThread.hpp"
43 #include "utilities/macros.hpp"
44
45 // CollectorPolicy methods
46
47 CollectorPolicy::CollectorPolicy() :
48 _space_alignment(0),
49 _heap_alignment(0),
50 _initial_heap_byte_size(InitialHeapSize),
51 _max_heap_byte_size(MaxHeapSize),
52 _min_heap_byte_size(Arguments::min_heap_size()),
53 _size_policy(NULL),
54 _should_clear_all_soft_refs(false),
55 _all_soft_refs_clear(false)
56 {}
57
58 #ifdef ASSERT
59 void CollectorPolicy::assert_flags() {
60 assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes");
61 assert(InitialHeapSize % _heap_alignment == 0, "InitialHeapSize alignment");
62 assert(MaxHeapSize % _heap_alignment == 0, "MaxHeapSize alignment");
63 }
64
65 void CollectorPolicy::assert_size_info() {
66 assert(InitialHeapSize == _initial_heap_byte_size, "Discrepancy between InitialHeapSize flag and local storage");
67 assert(MaxHeapSize == _max_heap_byte_size, "Discrepancy between MaxHeapSize flag and local storage");
68 assert(_max_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible minimum and maximum heap sizes");
69 assert(_initial_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible initial and minimum heap sizes");
70 assert(_max_heap_byte_size >= _initial_heap_byte_size, "Ergonomics decided on incompatible initial and maximum heap sizes");
71 assert(_min_heap_byte_size % _heap_alignment == 0, "min_heap_byte_size alignment");
72 assert(_initial_heap_byte_size % _heap_alignment == 0, "initial_heap_byte_size alignment");
74 }
75 #endif // ASSERT
76
77 void CollectorPolicy::initialize_flags() {
78 assert(_space_alignment != 0, "Space alignment not set up properly");
79 assert(_heap_alignment != 0, "Heap alignment not set up properly");
80 assert(_heap_alignment >= _space_alignment,
81 "heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,
82 _heap_alignment, _space_alignment);
83 assert(_heap_alignment % _space_alignment == 0,
84 "heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
85 _heap_alignment, _space_alignment);
86
87 if (FLAG_IS_CMDLINE(MaxHeapSize)) {
88 if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
89 vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size");
90 }
91 if (_min_heap_byte_size != 0 && MaxHeapSize < _min_heap_byte_size) {
92 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
93 }
94 }
95
96 // Check heap parameter properties
97 if (MaxHeapSize < 2 * M) {
98 vm_exit_during_initialization("Too small maximum heap");
99 }
100 if (InitialHeapSize < M) {
101 vm_exit_during_initialization("Too small initial heap");
102 }
103 if (_min_heap_byte_size < M) {
104 vm_exit_during_initialization("Too small minimum heap");
105 }
106
107 // User inputs from -Xmx and -Xms must be aligned
108 _min_heap_byte_size = align_size_up(_min_heap_byte_size, _heap_alignment);
109 size_t aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
110 size_t aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
111
112 // Write back to flags if the values changed
113 if (aligned_initial_heap_size != InitialHeapSize) {
266 assert(_min_young_size + _min_old_size <= _min_heap_byte_size, "Minimum generation sizes exceed minimum heap size");
267 assert(_initial_young_size + _initial_old_size == _initial_heap_byte_size, "Initial generation sizes should match initial heap size");
268 assert(_max_young_size + _max_old_size == _max_heap_byte_size, "Maximum generation sizes should match maximum heap size");
269 }
270 #endif // ASSERT
271
272 void GenCollectorPolicy::initialize_flags() {
273 CollectorPolicy::initialize_flags();
274
275 assert(_gen_alignment != 0, "Generation alignment not set up properly");
276 assert(_heap_alignment >= _gen_alignment,
277 "heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT,
278 _heap_alignment, _gen_alignment);
279 assert(_gen_alignment % _space_alignment == 0,
280 "gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
281 _gen_alignment, _space_alignment);
282 assert(_heap_alignment % _gen_alignment == 0,
283 "heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT,
284 _heap_alignment, _gen_alignment);
285
286 // All generational heaps have a young gen; handle those flags here
287
288 // Make sure the heap is large enough for two generations
289 size_t smallest_new_size = young_gen_size_lower_bound();
290 size_t smallest_heap_size = align_size_up(smallest_new_size + old_gen_size_lower_bound(),
291 _heap_alignment);
292 if (MaxHeapSize < smallest_heap_size) {
293 FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size);
294 _max_heap_byte_size = MaxHeapSize;
295 }
296 // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size
297 if (_min_heap_byte_size < smallest_heap_size) {
298 _min_heap_byte_size = smallest_heap_size;
299 if (InitialHeapSize < _min_heap_byte_size) {
300 FLAG_SET_ERGO(size_t, InitialHeapSize, smallest_heap_size);
301 _initial_heap_byte_size = smallest_heap_size;
302 }
303 }
304
305 // Make sure NewSize allows an old generation to fit even if set on the command line
306 if (FLAG_IS_CMDLINE(NewSize) && NewSize >= _initial_heap_byte_size) {
307 log_warning(gc, ergo)("NewSize was set larger than initial heap size, will use initial heap size.");
308 FLAG_SET_ERGO(size_t, NewSize, bound_minus_alignment(NewSize, _initial_heap_byte_size));
309 }
310
311 // Now take the actual NewSize into account. We will silently increase NewSize
312 // if the user specified a smaller or unaligned value.
313 size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize);
314 bounded_new_size = MAX2(smallest_new_size, (size_t)align_size_down(bounded_new_size, _gen_alignment));
315 if (bounded_new_size != NewSize) {
316 FLAG_SET_ERGO(size_t, NewSize, bounded_new_size);
317 }
318 _min_young_size = smallest_new_size;
319 _initial_young_size = NewSize;
320
321 if (!FLAG_IS_DEFAULT(MaxNewSize)) {
322 if (MaxNewSize >= MaxHeapSize) {
323 // Make sure there is room for an old generation
324 size_t smaller_max_new_size = MaxHeapSize - _gen_alignment;
325 if (FLAG_IS_CMDLINE(MaxNewSize)) {
326 log_warning(gc, ergo)("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "
327 "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.",
328 MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
329 }
330 FLAG_SET_ERGO(size_t, MaxNewSize, smaller_max_new_size);
331 if (NewSize > MaxNewSize) {
332 FLAG_SET_ERGO(size_t, NewSize, MaxNewSize);
333 _initial_young_size = NewSize;
334 }
335 } else if (MaxNewSize < _initial_young_size) {
336 FLAG_SET_ERGO(size_t, MaxNewSize, _initial_young_size);
339 }
340 _max_young_size = MaxNewSize;
341 }
342
343 if (NewSize > MaxNewSize) {
344 // At this point this should only happen if the user specifies a large NewSize and/or
345 // a small (but not too small) MaxNewSize.
346 if (FLAG_IS_CMDLINE(MaxNewSize)) {
347 log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
348 "A new max generation size of " SIZE_FORMAT "k will be used.",
349 NewSize/K, MaxNewSize/K, NewSize/K);
350 }
351 FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
352 _max_young_size = MaxNewSize;
353 }
354
355 if (SurvivorRatio < 1 || NewRatio < 1) {
356 vm_exit_during_initialization("Invalid young gen ratio specified");
357 }
358
359 if (OldSize < old_gen_size_lower_bound()) {
360 FLAG_SET_ERGO(size_t, OldSize, old_gen_size_lower_bound());
361 }
362 if (!is_size_aligned(OldSize, _gen_alignment)) {
363 FLAG_SET_ERGO(size_t, OldSize, align_size_down(OldSize, _gen_alignment));
364 }
365
366 if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {
367 // NewRatio will be used later to set the young generation size so we use
368 // it to calculate how big the heap should be based on the requested OldSize
369 // and NewRatio.
370 assert(NewRatio > 0, "NewRatio should have been set up earlier");
371 size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
372
373 calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment);
374 FLAG_SET_ERGO(size_t, MaxHeapSize, calculated_heapsize);
375 _max_heap_byte_size = MaxHeapSize;
376 FLAG_SET_ERGO(size_t, InitialHeapSize, calculated_heapsize);
377 _initial_heap_byte_size = InitialHeapSize;
378 }
379
380 // Adjust NewSize and OldSize or MaxHeapSize to match each other
381 if (NewSize + OldSize > MaxHeapSize) {
382 if (FLAG_IS_CMDLINE(MaxHeapSize)) {
383 // Somebody has set a maximum heap size with the intention that we should not
384 // exceed it. Adjust New/OldSize as necessary.
385 size_t calculated_size = NewSize + OldSize;
386 double shrink_factor = (double) MaxHeapSize / calculated_size;
387 size_t smaller_new_size = align_size_down((size_t)(NewSize * shrink_factor), _gen_alignment);
388 FLAG_SET_ERGO(size_t, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
389 _initial_young_size = NewSize;
390
391 // OldSize is already aligned because above we aligned MaxHeapSize to
392 // _heap_alignment, and we just made sure that NewSize is aligned to
393 // _gen_alignment. In initialize_flags() we verified that _heap_alignment
394 // is a multiple of _gen_alignment.
395 FLAG_SET_ERGO(size_t, OldSize, MaxHeapSize - NewSize);
396 } else {
397 FLAG_SET_ERGO(size_t, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
398 _max_heap_byte_size = MaxHeapSize;
399 }
400 }
401
402 // Update NewSize, if possible, to avoid sizing the young gen too small when only
|