comparison src/share/vm/memory/collectorPolicy.cpp @ 13060:8f07aa079343

8016309: assert(eden_size > 0 && survivor_size > 0) failed: just checking 7057939: jmap shows MaxNewSize=4GB when Java is using parallel collector Summary: Major cleanup of the collectorpolicy classes Reviewed-by: tschatzl, jcoomes
author jwilhelm
date Fri, 01 Nov 2013 17:09:38 +0100
parents 46d7652b223c
children 3ad2b68d107e
comparison
equal deleted inserted replaced
13059:46d7652b223c 13060:8f07aa079343
45 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp" 45 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"
46 #endif // INCLUDE_ALL_GCS 46 #endif // INCLUDE_ALL_GCS
47 47
48 // CollectorPolicy methods. 48 // CollectorPolicy methods.
49 49
50 CollectorPolicy::CollectorPolicy() :
51 _space_alignment(0),
52 _heap_alignment(0),
53 _initial_heap_byte_size(InitialHeapSize),
54 _max_heap_byte_size(MaxHeapSize),
55 _min_heap_byte_size(Arguments::min_heap_size()),
56 _max_heap_size_cmdline(false),
57 _size_policy(NULL),
58 _should_clear_all_soft_refs(false),
59 _all_soft_refs_clear(false)
60 {}
61
62 #ifdef ASSERT
63 void CollectorPolicy::assert_flags() {
64 assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes");
65 assert(InitialHeapSize % _heap_alignment == 0, "InitialHeapSize alignment");
66 assert(MaxHeapSize % _heap_alignment == 0, "MaxHeapSize alignment");
67 }
68
69 void CollectorPolicy::assert_size_info() {
70 assert(InitialHeapSize == _initial_heap_byte_size, "Discrepancy between InitialHeapSize flag and local storage");
71 assert(MaxHeapSize == _max_heap_byte_size, "Discrepancy between MaxHeapSize flag and local storage");
72 assert(_max_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible minimum and maximum heap sizes");
73 assert(_initial_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible initial and minimum heap sizes");
74 assert(_max_heap_byte_size >= _initial_heap_byte_size, "Ergonomics decided on incompatible initial and maximum heap sizes");
75 assert(_min_heap_byte_size % _heap_alignment == 0, "min_heap_byte_size alignment");
76 assert(_initial_heap_byte_size % _heap_alignment == 0, "initial_heap_byte_size alignment");
77 assert(_max_heap_byte_size % _heap_alignment == 0, "max_heap_byte_size alignment");
78 }
79 #endif // ASSERT
80
50 void CollectorPolicy::initialize_flags() { 81 void CollectorPolicy::initialize_flags() {
51 assert(_max_alignment >= _min_alignment, 82 assert(_space_alignment != 0, "Space alignment not set up properly");
52 err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT, 83 assert(_heap_alignment != 0, "Heap alignment not set up properly");
53 _max_alignment, _min_alignment)); 84 assert(_heap_alignment >= _space_alignment,
54 assert(_max_alignment % _min_alignment == 0, 85 err_msg("heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,
55 err_msg("max_alignment: " SIZE_FORMAT " not aligned by min_alignment: " SIZE_FORMAT, 86 _heap_alignment, _space_alignment));
56 _max_alignment, _min_alignment)); 87 assert(_heap_alignment % _space_alignment == 0,
57 88 err_msg("heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
58 if (MaxHeapSize < InitialHeapSize) { 89 _heap_alignment, _space_alignment));
59 vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); 90
60 } 91 if (FLAG_IS_CMDLINE(MaxHeapSize)) {
61 92 if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
62 MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, _min_alignment); 93 vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size");
63 } 94 }
64 95 if (_min_heap_byte_size != 0 && MaxHeapSize < _min_heap_byte_size) {
65 void CollectorPolicy::initialize_size_info() { 96 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
66 // User inputs from -mx and ms must be aligned 97 }
67 _min_heap_byte_size = align_size_up(Arguments::min_heap_size(), _min_alignment); 98 _max_heap_size_cmdline = true;
68 _initial_heap_byte_size = align_size_up(InitialHeapSize, _min_alignment); 99 }
69 _max_heap_byte_size = align_size_up(MaxHeapSize, _max_alignment);
70 100
71 // Check heap parameter properties 101 // Check heap parameter properties
72 if (_initial_heap_byte_size < M) { 102 if (InitialHeapSize < M) {
73 vm_exit_during_initialization("Too small initial heap"); 103 vm_exit_during_initialization("Too small initial heap");
74 } 104 }
75 // Check heap parameter properties
76 if (_min_heap_byte_size < M) { 105 if (_min_heap_byte_size < M) {
77 vm_exit_during_initialization("Too small minimum heap"); 106 vm_exit_during_initialization("Too small minimum heap");
78 } 107 }
79 if (_initial_heap_byte_size <= NewSize) { 108
80 // make sure there is at least some room in old space 109 // User inputs from -Xmx and -Xms must be aligned
81 vm_exit_during_initialization("Too small initial heap for new size specified"); 110 _min_heap_byte_size = align_size_up(_min_heap_byte_size, _heap_alignment);
82 } 111 uintx aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
83 if (_max_heap_byte_size < _min_heap_byte_size) { 112 uintx aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
84 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified"); 113
85 } 114 // Write back to flags if the values changed
86 if (_initial_heap_byte_size < _min_heap_byte_size) { 115 if (aligned_initial_heap_size != InitialHeapSize) {
116 FLAG_SET_ERGO(uintx, InitialHeapSize, aligned_initial_heap_size);
117 }
118 if (aligned_max_heap_size != MaxHeapSize) {
119 FLAG_SET_ERGO(uintx, MaxHeapSize, aligned_max_heap_size);
120 }
121
122 if (FLAG_IS_CMDLINE(InitialHeapSize) && _min_heap_byte_size != 0 &&
123 InitialHeapSize < _min_heap_byte_size) {
87 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified"); 124 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
88 } 125 }
89 if (_max_heap_byte_size < _initial_heap_byte_size) { 126 if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
90 vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified"); 127 FLAG_SET_ERGO(uintx, MaxHeapSize, InitialHeapSize);
91 } 128 } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {
92 129 FLAG_SET_ERGO(uintx, InitialHeapSize, MaxHeapSize);
130 if (InitialHeapSize < _min_heap_byte_size) {
131 _min_heap_byte_size = InitialHeapSize;
132 }
133 }
134
135 _initial_heap_byte_size = InitialHeapSize;
136 _max_heap_byte_size = MaxHeapSize;
137
138 FLAG_SET_ERGO(uintx, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));
139
140 DEBUG_ONLY(CollectorPolicy::assert_flags();)
141 }
142
143 void CollectorPolicy::initialize_size_info() {
93 if (PrintGCDetails && Verbose) { 144 if (PrintGCDetails && Verbose) {
94 gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap " 145 gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
95 SIZE_FORMAT " Maximum heap " SIZE_FORMAT, 146 SIZE_FORMAT " Maximum heap " SIZE_FORMAT,
96 _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size); 147 _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
97 } 148 }
149
150 DEBUG_ONLY(CollectorPolicy::assert_size_info();)
98 } 151 }
99 152
100 bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) { 153 bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
101 bool result = _should_clear_all_soft_refs; 154 bool result = _should_clear_all_soft_refs;
102 set_should_clear_all_soft_refs(false); 155 set_should_clear_all_soft_refs(false);
116 _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near(); 169 _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near();
117 } 170 }
118 _all_soft_refs_clear = true; 171 _all_soft_refs_clear = true;
119 } 172 }
120 173
121 size_t CollectorPolicy::compute_max_alignment() { 174 size_t CollectorPolicy::compute_heap_alignment() {
122 // The card marking array and the offset arrays for old generations are 175 // The card marking array and the offset arrays for old generations are
123 // committed in os pages as well. Make sure they are entirely full (to 176 // committed in os pages as well. Make sure they are entirely full (to
124 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1 177 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
125 // byte entry and the os page size is 4096, the maximum heap size should 178 // byte entry and the os page size is 4096, the maximum heap size should
126 // be 512*4096 = 2MB aligned. 179 // be 512*4096 = 2MB aligned.
143 return alignment; 196 return alignment;
144 } 197 }
145 198
146 // GenCollectorPolicy methods. 199 // GenCollectorPolicy methods.
147 200
201 GenCollectorPolicy::GenCollectorPolicy() :
202 _min_gen0_size(0),
203 _initial_gen0_size(0),
204 _max_gen0_size(0),
205 _gen_alignment(0),
206 _generations(NULL)
207 {}
208
148 size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) { 209 size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
149 return align_size_down_bounded(base_size / (NewRatio + 1), _min_alignment); 210 return align_size_down_bounded(base_size / (NewRatio + 1), _gen_alignment);
150 } 211 }
151 212
152 size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size, 213 size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
153 size_t maximum_size) { 214 size_t maximum_size) {
154 size_t alignment = _min_alignment; 215 size_t max_minus = maximum_size - _gen_alignment;
155 size_t max_minus = maximum_size - alignment;
156 return desired_size < max_minus ? desired_size : max_minus; 216 return desired_size < max_minus ? desired_size : max_minus;
157 } 217 }
158 218
159 219
160 void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, 220 void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
166 init_survivor_size, 226 init_survivor_size,
167 max_gc_pause_sec, 227 max_gc_pause_sec,
168 GCTimeRatio); 228 GCTimeRatio);
169 } 229 }
170 230
231 size_t GenCollectorPolicy::young_gen_size_lower_bound() {
232 // The young generation must be aligned and have room for eden + two survivors
233 return align_size_up(3 * _space_alignment, _gen_alignment);
234 }
235
236 #ifdef ASSERT
237 void GenCollectorPolicy::assert_flags() {
238 CollectorPolicy::assert_flags();
239 assert(NewSize >= _min_gen0_size, "Ergonomics decided on a too small young gen size");
240 assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes");
241 assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes");
242 assert(NewSize % _gen_alignment == 0, "NewSize alignment");
243 assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % _gen_alignment == 0, "MaxNewSize alignment");
244 }
245
246 void TwoGenerationCollectorPolicy::assert_flags() {
247 GenCollectorPolicy::assert_flags();
248 assert(OldSize + NewSize <= MaxHeapSize, "Ergonomics decided on incompatible generation and heap sizes");
249 assert(OldSize % _gen_alignment == 0, "OldSize alignment");
250 }
251
252 void GenCollectorPolicy::assert_size_info() {
253 CollectorPolicy::assert_size_info();
254 // GenCollectorPolicy::initialize_size_info may update the MaxNewSize
255 assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes");
256 assert(NewSize == _initial_gen0_size, "Discrepancy between NewSize flag and local storage");
257 assert(MaxNewSize == _max_gen0_size, "Discrepancy between MaxNewSize flag and local storage");
258 assert(_min_gen0_size <= _initial_gen0_size, "Ergonomics decided on incompatible minimum and initial young gen sizes");
259 assert(_initial_gen0_size <= _max_gen0_size, "Ergonomics decided on incompatible initial and maximum young gen sizes");
260 assert(_min_gen0_size % _gen_alignment == 0, "_min_gen0_size alignment");
261 assert(_initial_gen0_size % _gen_alignment == 0, "_initial_gen0_size alignment");
262 assert(_max_gen0_size % _gen_alignment == 0, "_max_gen0_size alignment");
263 }
264
265 void TwoGenerationCollectorPolicy::assert_size_info() {
266 GenCollectorPolicy::assert_size_info();
267 assert(OldSize == _initial_gen1_size, "Discrepancy between OldSize flag and local storage");
268 assert(_min_gen1_size <= _initial_gen1_size, "Ergonomics decided on incompatible minimum and initial old gen sizes");
269 assert(_initial_gen1_size <= _max_gen1_size, "Ergonomics decided on incompatible initial and maximum old gen sizes");
270 assert(_max_gen1_size % _gen_alignment == 0, "_max_gen1_size alignment");
271 assert(_initial_gen1_size % _gen_alignment == 0, "_initial_gen1_size alignment");
272 assert(_max_heap_byte_size <= (_max_gen0_size + _max_gen1_size), "Total maximum heap sizes must be sum of generation maximum sizes");
273 }
274 #endif // ASSERT
275
171 void GenCollectorPolicy::initialize_flags() { 276 void GenCollectorPolicy::initialize_flags() {
172 // All sizes must be multiples of the generation granularity.
173 _min_alignment = (uintx) Generation::GenGrain;
174 _max_alignment = compute_max_alignment();
175
176 CollectorPolicy::initialize_flags(); 277 CollectorPolicy::initialize_flags();
177 278
178 // All generational heaps have a youngest gen; handle those flags here. 279 assert(_gen_alignment != 0, "Generation alignment not set up properly");
179 280 assert(_heap_alignment >= _gen_alignment,
180 // Adjust max size parameters 281 err_msg("heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT,
282 _heap_alignment, _gen_alignment));
283 assert(_gen_alignment % _space_alignment == 0,
284 err_msg("gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
285 _gen_alignment, _space_alignment));
286 assert(_heap_alignment % _gen_alignment == 0,
287 err_msg("heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT,
288 _heap_alignment, _gen_alignment));
289
290 // All generational heaps have a youngest gen; handle those flags here
291
292 // Make sure the heap is large enough for two generations
293 uintx smallest_new_size = young_gen_size_lower_bound();
294 uintx smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment),
295 _heap_alignment);
296 if (MaxHeapSize < smallest_heap_size) {
297 FLAG_SET_ERGO(uintx, MaxHeapSize, smallest_heap_size);
298 _max_heap_byte_size = MaxHeapSize;
299 }
300 // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size
301 if (_min_heap_byte_size < smallest_heap_size) {
302 _min_heap_byte_size = smallest_heap_size;
303 if (InitialHeapSize < _min_heap_byte_size) {
304 FLAG_SET_ERGO(uintx, InitialHeapSize, smallest_heap_size);
305 _initial_heap_byte_size = smallest_heap_size;
306 }
307 }
308
309 // Now take the actual NewSize into account. We will silently increase NewSize
310 // if the user specified a smaller value.
311 smallest_new_size = MAX2(smallest_new_size, (uintx)align_size_down(NewSize, _gen_alignment));
312 if (smallest_new_size != NewSize) {
313 FLAG_SET_ERGO(uintx, NewSize, smallest_new_size);
314 }
315 _initial_gen0_size = NewSize;
316
317 if (!FLAG_IS_DEFAULT(MaxNewSize)) {
318 uintx min_new_size = MAX2(_gen_alignment, _min_gen0_size);
319
320 if (MaxNewSize >= MaxHeapSize) {
321 // Make sure there is room for an old generation
322 uintx smaller_max_new_size = MaxHeapSize - _gen_alignment;
323 if (FLAG_IS_CMDLINE(MaxNewSize)) {
324 warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "
325 "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.",
326 MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
327 }
328 FLAG_SET_ERGO(uintx, MaxNewSize, smaller_max_new_size);
329 if (NewSize > MaxNewSize) {
330 FLAG_SET_ERGO(uintx, NewSize, MaxNewSize);
331 _initial_gen0_size = NewSize;
332 }
333 } else if (MaxNewSize < min_new_size) {
334 FLAG_SET_ERGO(uintx, MaxNewSize, min_new_size);
335 } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) {
336 FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));
337 }
338 _max_gen0_size = MaxNewSize;
339 }
340
181 if (NewSize > MaxNewSize) { 341 if (NewSize > MaxNewSize) {
182 MaxNewSize = NewSize; 342 // At this point this should only happen if the user specifies a large NewSize and/or
183 } 343 // a small (but not too small) MaxNewSize.
184 NewSize = align_size_down(NewSize, _min_alignment); 344 if (FLAG_IS_CMDLINE(MaxNewSize)) {
185 MaxNewSize = align_size_down(MaxNewSize, _min_alignment); 345 warning("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
186 346 "A new max generation size of " SIZE_FORMAT "k will be used.",
187 // Check validity of heap flags 347 NewSize/K, MaxNewSize/K, NewSize/K);
188 assert(NewSize % _min_alignment == 0, "eden space alignment"); 348 }
189 assert(MaxNewSize % _min_alignment == 0, "survivor space alignment"); 349 FLAG_SET_ERGO(uintx, MaxNewSize, NewSize);
190 350 _max_gen0_size = MaxNewSize;
191 if (NewSize < 3 * _min_alignment) {
192 // make sure there room for eden and two survivor spaces
193 vm_exit_during_initialization("Too small new size specified");
194 } 351 }
195 352
196 if (SurvivorRatio < 1 || NewRatio < 1) { 353 if (SurvivorRatio < 1 || NewRatio < 1) {
197 vm_exit_during_initialization("Invalid young gen ratio specified"); 354 vm_exit_during_initialization("Invalid young gen ratio specified");
198 } 355 }
356
357 DEBUG_ONLY(GenCollectorPolicy::assert_flags();)
199 } 358 }
200 359
201 void TwoGenerationCollectorPolicy::initialize_flags() { 360 void TwoGenerationCollectorPolicy::initialize_flags() {
202 GenCollectorPolicy::initialize_flags(); 361 GenCollectorPolicy::initialize_flags();
203 362
204 OldSize = align_size_down(OldSize, _min_alignment); 363 if (!is_size_aligned(OldSize, _gen_alignment)) {
205 364 FLAG_SET_ERGO(uintx, OldSize, align_size_down(OldSize, _gen_alignment));
206 if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(NewSize)) { 365 }
366
367 if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {
207 // NewRatio will be used later to set the young generation size so we use 368 // NewRatio will be used later to set the young generation size so we use
208 // it to calculate how big the heap should be based on the requested OldSize 369 // it to calculate how big the heap should be based on the requested OldSize
209 // and NewRatio. 370 // and NewRatio.
210 assert(NewRatio > 0, "NewRatio should have been set up earlier"); 371 assert(NewRatio > 0, "NewRatio should have been set up earlier");
211 size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1); 372 size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
212 373
213 calculated_heapsize = align_size_up(calculated_heapsize, _max_alignment); 374 calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment);
214 MaxHeapSize = calculated_heapsize; 375 FLAG_SET_ERGO(uintx, MaxHeapSize, calculated_heapsize);
215 InitialHeapSize = calculated_heapsize; 376 _max_heap_byte_size = MaxHeapSize;
216 } 377 FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize);
217 MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment); 378 _initial_heap_byte_size = InitialHeapSize;
379 }
218 380
219 // adjust max heap size if necessary 381 // adjust max heap size if necessary
220 if (NewSize + OldSize > MaxHeapSize) { 382 if (NewSize + OldSize > MaxHeapSize) {
221 if (FLAG_IS_CMDLINE(MaxHeapSize)) { 383 if (_max_heap_size_cmdline) {
222 // somebody set a maximum heap size with the intention that we should not 384 // somebody set a maximum heap size with the intention that we should not
223 // exceed it. Adjust New/OldSize as necessary. 385 // exceed it. Adjust New/OldSize as necessary.
224 uintx calculated_size = NewSize + OldSize; 386 uintx calculated_size = NewSize + OldSize;
225 double shrink_factor = (double) MaxHeapSize / calculated_size; 387 double shrink_factor = (double) MaxHeapSize / calculated_size;
226 // align 388 uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment);
227 NewSize = align_size_down((uintx) (NewSize * shrink_factor), _min_alignment); 389 FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
390 _initial_gen0_size = NewSize;
391
228 // OldSize is already aligned because above we aligned MaxHeapSize to 392 // OldSize is already aligned because above we aligned MaxHeapSize to
229 // _max_alignment, and we just made sure that NewSize is aligned to 393 // _heap_alignment, and we just made sure that NewSize is aligned to
230 // _min_alignment. In initialize_flags() we verified that _max_alignment 394 // _gen_alignment. In initialize_flags() we verified that _heap_alignment
231 // is a multiple of _min_alignment. 395 // is a multiple of _gen_alignment.
232 OldSize = MaxHeapSize - NewSize; 396 FLAG_SET_ERGO(uintx, OldSize, MaxHeapSize - NewSize);
233 } else { 397 } else {
234 MaxHeapSize = NewSize + OldSize; 398 FLAG_SET_ERGO(uintx, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
235 } 399 _max_heap_byte_size = MaxHeapSize;
236 } 400 }
237 // need to do this again 401 }
238 MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment);
239
240 // adjust max heap size if necessary
241 if (NewSize + OldSize > MaxHeapSize) {
242 if (FLAG_IS_CMDLINE(MaxHeapSize)) {
243 // somebody set a maximum heap size with the intention that we should not
244 // exceed it. Adjust New/OldSize as necessary.
245 uintx calculated_size = NewSize + OldSize;
246 double shrink_factor = (double) MaxHeapSize / calculated_size;
247 // align
248 NewSize = align_size_down((uintx) (NewSize * shrink_factor), _min_alignment);
249 // OldSize is already aligned because above we aligned MaxHeapSize to
250 // _max_alignment, and we just made sure that NewSize is aligned to
251 // _min_alignment. In initialize_flags() we verified that _max_alignment
252 // is a multiple of _min_alignment.
253 OldSize = MaxHeapSize - NewSize;
254 } else {
255 MaxHeapSize = NewSize + OldSize;
256 }
257 }
258 // need to do this again
259 MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment);
260 402
261 always_do_update_barrier = UseConcMarkSweepGC; 403 always_do_update_barrier = UseConcMarkSweepGC;
262 404
263 // Check validity of heap flags 405 DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_flags();)
264 assert(OldSize % _min_alignment == 0, "old space alignment");
265 assert(MaxHeapSize % _max_alignment == 0, "maximum heap alignment");
266 } 406 }
267 407
268 // Values set on the command line win over any ergonomically 408 // Values set on the command line win over any ergonomically
269 // set command line parameters. 409 // set command line parameters.
270 // Ergonomic choice of parameters are done before this 410 // Ergonomic choice of parameters are done before this
275 // In the absence of explicitly set command line flags, policies 415 // In the absence of explicitly set command line flags, policies
276 // such as the use of NewRatio are used to size the generation. 416 // such as the use of NewRatio are used to size the generation.
277 void GenCollectorPolicy::initialize_size_info() { 417 void GenCollectorPolicy::initialize_size_info() {
278 CollectorPolicy::initialize_size_info(); 418 CollectorPolicy::initialize_size_info();
279 419
280 // _min_alignment is used for alignment within a generation. 420 // _space_alignment is used for alignment within a generation.
281 // There is additional alignment done down stream for some 421 // There is additional alignment done down stream for some
282 // collectors that sometimes causes unwanted rounding up of 422 // collectors that sometimes causes unwanted rounding up of
283 // generations sizes. 423 // generations sizes.
284 424
285 // Determine maximum size of gen0 425 // Determine maximum size of gen0
286 426
287 size_t max_new_size = 0; 427 size_t max_new_size = 0;
288 if (FLAG_IS_CMDLINE(MaxNewSize) || FLAG_IS_ERGO(MaxNewSize)) { 428 if (!FLAG_IS_DEFAULT(MaxNewSize)) {
289 if (MaxNewSize < _min_alignment) { 429 max_new_size = MaxNewSize;
290 max_new_size = _min_alignment;
291 }
292 if (MaxNewSize >= _max_heap_byte_size) {
293 max_new_size = align_size_down(_max_heap_byte_size - _min_alignment,
294 _min_alignment);
295 warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or "
296 "greater than the entire heap (" SIZE_FORMAT "k). A "
297 "new generation size of " SIZE_FORMAT "k will be used.",
298 MaxNewSize/K, _max_heap_byte_size/K, max_new_size/K);
299 } else {
300 max_new_size = align_size_down(MaxNewSize, _min_alignment);
301 }
302
303 // The case for FLAG_IS_ERGO(MaxNewSize) could be treated
304 // specially at this point to just use an ergonomically set
305 // MaxNewSize to set max_new_size. For cases with small
306 // heaps such a policy often did not work because the MaxNewSize
307 // was larger than the entire heap. The interpretation given
308 // to ergonomically set flags is that the flags are set
309 // by different collectors for their own special needs but
310 // are not allowed to badly shape the heap. This allows the
311 // different collectors to decide what's best for themselves
312 // without having to factor in the overall heap shape. It
313 // can be the case in the future that the collectors would
314 // only make "wise" ergonomics choices and this policy could
315 // just accept those choices. The choices currently made are
316 // not always "wise".
317 } else { 430 } else {
318 max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size); 431 max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size);
319 // Bound the maximum size by NewSize below (since it historically 432 // Bound the maximum size by NewSize below (since it historically
320 // would have been NewSize and because the NewRatio calculation could 433 // would have been NewSize and because the NewRatio calculation could
321 // yield a size that is too small) and bound it by MaxNewSize above. 434 // yield a size that is too small) and bound it by MaxNewSize above.
380 _min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size); 493 _min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size);
381 _initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size); 494 _initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size);
382 _min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size); 495 _min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size);
383 } 496 }
384 497
498 // Write back to flags if necessary
499 if (NewSize != _initial_gen0_size) {
500 FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size);
501 }
502
503 if (MaxNewSize != _max_gen0_size) {
504 FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size);
505 }
506
385 if (PrintGCDetails && Verbose) { 507 if (PrintGCDetails && Verbose) {
386 gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 " 508 gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
387 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, 509 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
388 _min_gen0_size, _initial_gen0_size, _max_gen0_size); 510 _min_gen0_size, _initial_gen0_size, _max_gen0_size);
389 } 511 }
512
513 DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
390 } 514 }
391 515
392 // Call this method during the sizing of the gen1 to make 516 // Call this method during the sizing of the gen1 to make
393 // adjustments to gen0 because of gen1 sizing policy. gen0 initially has 517 // adjustments to gen0 because of gen1 sizing policy. gen0 initially has
394 // the most freedom in sizing because it is done before the 518 // the most freedom in sizing because it is done before the
402 const size_t heap_size, 526 const size_t heap_size,
403 const size_t min_gen1_size) { 527 const size_t min_gen1_size) {
404 bool result = false; 528 bool result = false;
405 529
406 if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) { 530 if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) {
531 uintx smallest_new_size = young_gen_size_lower_bound();
407 if ((heap_size < (*gen0_size_ptr + min_gen1_size)) && 532 if ((heap_size < (*gen0_size_ptr + min_gen1_size)) &&
408 (heap_size >= min_gen1_size + _min_alignment)) { 533 (heap_size >= min_gen1_size + smallest_new_size)) {
409 // Adjust gen0 down to accommodate min_gen1_size 534 // Adjust gen0 down to accommodate min_gen1_size
410 *gen0_size_ptr = align_size_down_bounded(heap_size - min_gen1_size, _min_alignment); 535 *gen0_size_ptr = align_size_down_bounded(heap_size - min_gen1_size, _gen_alignment);
411 assert(*gen0_size_ptr > 0, "Min gen0 is too large"); 536 assert(*gen0_size_ptr > 0, "Min gen0 is too large");
412 result = true; 537 result = true;
413 } else { 538 } else {
414 *gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _min_alignment); 539 *gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _gen_alignment);
415 } 540 }
416 } 541 }
417 return result; 542 return result;
418 } 543 }
419 544
430 // At this point the minimum, initial and maximum sizes 555 // At this point the minimum, initial and maximum sizes
431 // of the overall heap and of gen0 have been determined. 556 // of the overall heap and of gen0 have been determined.
432 // The maximum gen1 size can be determined from the maximum gen0 557 // The maximum gen1 size can be determined from the maximum gen0
433 // and maximum heap size since no explicit flags exits 558 // and maximum heap size since no explicit flags exits
434 // for setting the gen1 maximum. 559 // for setting the gen1 maximum.
435 _max_gen1_size = _max_heap_byte_size - _max_gen0_size; 560 _max_gen1_size = MAX2(_max_heap_byte_size - _max_gen0_size, _gen_alignment);
436 _max_gen1_size = 561
437 MAX2((uintx)align_size_down(_max_gen1_size, _min_alignment), _min_alignment);
438 // If no explicit command line flag has been set for the 562 // If no explicit command line flag has been set for the
439 // gen1 size, use what is left for gen1. 563 // gen1 size, use what is left for gen1.
440 if (FLAG_IS_DEFAULT(OldSize) || FLAG_IS_ERGO(OldSize)) { 564 if (!FLAG_IS_CMDLINE(OldSize)) {
441 // The user has not specified any value or ergonomics 565 // The user has not specified any value but the ergonomics
442 // has chosen a value (which may or may not be consistent 566 // may have chosen a value (which may or may not be consistent
443 // with the overall heap size). In either case make 567 // with the overall heap size). In either case make
444 // the minimum, maximum and initial sizes consistent 568 // the minimum, maximum and initial sizes consistent
445 // with the gen0 sizes and the overall heap sizes. 569 // with the gen0 sizes and the overall heap sizes.
446 assert(_min_heap_byte_size > _min_gen0_size, 570 _min_gen1_size = MAX2(_min_heap_byte_size - _min_gen0_size, _gen_alignment);
447 "gen0 has an unexpected minimum size"); 571 _initial_gen1_size = MAX2(_initial_heap_byte_size - _initial_gen0_size, _gen_alignment);
448 _min_gen1_size = _min_heap_byte_size - _min_gen0_size; 572 // _max_gen1_size has already been made consistent above
449 _min_gen1_size = 573 FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);
450 MAX2((uintx)align_size_down(_min_gen1_size, _min_alignment), _min_alignment);
451 _initial_gen1_size = _initial_heap_byte_size - _initial_gen0_size;
452 _initial_gen1_size =
453 MAX2((uintx)align_size_down(_initial_gen1_size, _min_alignment), _min_alignment);
454 } else { 574 } else {
455 // It's been explicitly set on the command line. Use the 575 // It's been explicitly set on the command line. Use the
456 // OldSize and then determine the consequences. 576 // OldSize and then determine the consequences.
457 _min_gen1_size = OldSize; 577 _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size);
458 _initial_gen1_size = OldSize; 578 _initial_gen1_size = OldSize;
459 579
460 // If the user has explicitly set an OldSize that is inconsistent 580 // If the user has explicitly set an OldSize that is inconsistent
461 // with other command line flags, issue a warning. 581 // with other command line flags, issue a warning.
462 // The generation minimums and the overall heap mimimum should 582 // The generation minimums and the overall heap mimimum should
463 // be within one heap alignment. 583 // be within one generation alignment.
464 if ((_min_gen1_size + _min_gen0_size + _min_alignment) < _min_heap_byte_size) { 584 if ((_min_gen1_size + _min_gen0_size + _gen_alignment) < _min_heap_byte_size) {
465 warning("Inconsistency between minimum heap size and minimum " 585 warning("Inconsistency between minimum heap size and minimum "
466 "generation sizes: using minimum heap = " SIZE_FORMAT, 586 "generation sizes: using minimum heap = " SIZE_FORMAT,
467 _min_heap_byte_size); 587 _min_heap_byte_size);
468 } 588 }
469 if (OldSize > _max_gen1_size) { 589 if (OldSize > _max_gen1_size) {
473 _max_heap_byte_size); 593 _max_heap_byte_size);
474 } 594 }
475 // If there is an inconsistency between the OldSize and the minimum and/or 595 // If there is an inconsistency between the OldSize and the minimum and/or
476 // initial size of gen0, since OldSize was explicitly set, OldSize wins. 596 // initial size of gen0, since OldSize was explicitly set, OldSize wins.
477 if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size, 597 if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
478 _min_heap_byte_size, OldSize)) { 598 _min_heap_byte_size, _min_gen1_size)) {
479 if (PrintGCDetails && Verbose) { 599 if (PrintGCDetails && Verbose) {
480 gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 " 600 gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
481 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, 601 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
482 _min_gen0_size, _initial_gen0_size, _max_gen0_size); 602 _min_gen0_size, _initial_gen0_size, _max_gen0_size);
483 } 603 }
484 } 604 }
485 // Initial size 605 // Initial size
486 if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size, 606 if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
487 _initial_heap_byte_size, OldSize)) { 607 _initial_heap_byte_size, _initial_gen1_size)) {
488 if (PrintGCDetails && Verbose) { 608 if (PrintGCDetails && Verbose) {
489 gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 " 609 gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
490 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT, 610 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
491 _min_gen0_size, _initial_gen0_size, _max_gen0_size); 611 _min_gen0_size, _initial_gen0_size, _max_gen0_size);
492 } 612 }
497 617
498 // Check that min gen1 <= initial gen1 <= max gen1 618 // Check that min gen1 <= initial gen1 <= max gen1
499 _initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size); 619 _initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size);
500 _initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size); 620 _initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size);
501 621
622 // Write back to flags if necessary
623 if (NewSize != _initial_gen0_size) {
624 FLAG_SET_ERGO(uintx, NewSize, _max_gen0_size);
625 }
626
627 if (MaxNewSize != _max_gen0_size) {
628 FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size);
629 }
630
631 if (OldSize != _initial_gen1_size) {
632 FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);
633 }
634
502 if (PrintGCDetails && Verbose) { 635 if (PrintGCDetails && Verbose) {
503 gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 " 636 gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 "
504 SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT, 637 SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT,
505 _min_gen1_size, _initial_gen1_size, _max_gen1_size); 638 _min_gen1_size, _initial_gen1_size, _max_gen1_size);
506 } 639 }
640
641 DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_size_info();)
507 } 642 }
508 643
509 HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size, 644 HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
510 bool is_tlab, 645 bool is_tlab,
511 bool* gc_overhead_limit_was_exceeded) { 646 bool* gc_overhead_limit_was_exceeded) {
824 959
825 // 960 //
826 // MarkSweepPolicy methods 961 // MarkSweepPolicy methods
827 // 962 //
828 963
829 MarkSweepPolicy::MarkSweepPolicy() { 964 void MarkSweepPolicy::initialize_alignments() {
830 initialize_all(); 965 _space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
966 _heap_alignment = compute_heap_alignment();
831 } 967 }
832 968
833 void MarkSweepPolicy::initialize_generations() { 969 void MarkSweepPolicy::initialize_generations() {
834 _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL); 970 _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
835 if (_generations == NULL) { 971 if (_generations == NULL) {