Thu, 26 Jun 2014 11:36:58 +0200
8047818: G1 HeapRegions can no longer be ContiguousSpaces
Summary: Change parent of G1OffsetTableContigSpace to CompactibleSpace, reimplement missing functionality
Reviewed-by: stefank, jmasa, tschatzl
1 /*
2 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #include "precompiled.hpp"
26 #include "gc_implementation/shared/adaptiveSizePolicy.hpp"
27 #include "gc_implementation/shared/gcPolicyCounters.hpp"
28 #include "gc_implementation/shared/vmGCOperations.hpp"
29 #include "memory/cardTableRS.hpp"
30 #include "memory/collectorPolicy.hpp"
31 #include "memory/gcLocker.inline.hpp"
32 #include "memory/genCollectedHeap.hpp"
33 #include "memory/generationSpec.hpp"
34 #include "memory/space.hpp"
35 #include "memory/universe.hpp"
36 #include "runtime/arguments.hpp"
37 #include "runtime/globals_extension.hpp"
38 #include "runtime/handles.inline.hpp"
39 #include "runtime/java.hpp"
40 #include "runtime/thread.inline.hpp"
41 #include "runtime/vmThread.hpp"
42 #include "utilities/macros.hpp"
43 #if INCLUDE_ALL_GCS
44 #include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
45 #include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"
46 #endif // INCLUDE_ALL_GCS
48 // CollectorPolicy methods.
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 {}
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 }
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
81 void CollectorPolicy::initialize_flags() {
82 assert(_space_alignment != 0, "Space alignment not set up properly");
83 assert(_heap_alignment != 0, "Heap alignment not set up properly");
84 assert(_heap_alignment >= _space_alignment,
85 err_msg("heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,
86 _heap_alignment, _space_alignment));
87 assert(_heap_alignment % _space_alignment == 0,
88 err_msg("heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
89 _heap_alignment, _space_alignment));
91 if (FLAG_IS_CMDLINE(MaxHeapSize)) {
92 if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
93 vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size");
94 }
95 if (_min_heap_byte_size != 0 && MaxHeapSize < _min_heap_byte_size) {
96 vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
97 }
98 _max_heap_size_cmdline = true;
99 }
101 // Check heap parameter properties
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 }
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 uintx aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
112 uintx aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
114 // Write back to flags if the values changed
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 }
122 if (FLAG_IS_CMDLINE(InitialHeapSize) && _min_heap_byte_size != 0 &&
123 InitialHeapSize < _min_heap_byte_size) {
124 vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
125 }
126 if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
127 FLAG_SET_ERGO(uintx, MaxHeapSize, InitialHeapSize);
128 } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {
129 FLAG_SET_ERGO(uintx, InitialHeapSize, MaxHeapSize);
130 if (InitialHeapSize < _min_heap_byte_size) {
131 _min_heap_byte_size = InitialHeapSize;
132 }
133 }
135 _initial_heap_byte_size = InitialHeapSize;
136 _max_heap_byte_size = MaxHeapSize;
138 FLAG_SET_ERGO(uintx, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));
140 DEBUG_ONLY(CollectorPolicy::assert_flags();)
141 }
143 void CollectorPolicy::initialize_size_info() {
144 if (PrintGCDetails && Verbose) {
145 gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
146 SIZE_FORMAT " Maximum heap " SIZE_FORMAT,
147 _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
148 }
150 DEBUG_ONLY(CollectorPolicy::assert_size_info();)
151 }
153 bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
154 bool result = _should_clear_all_soft_refs;
155 set_should_clear_all_soft_refs(false);
156 return result;
157 }
159 GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap,
160 int max_covered_regions) {
161 return new CardTableRS(whole_heap, max_covered_regions);
162 }
164 void CollectorPolicy::cleared_all_soft_refs() {
165 // If near gc overhear limit, continue to clear SoftRefs. SoftRefs may
166 // have been cleared in the last collection but if the gc overhear
167 // limit continues to be near, SoftRefs should still be cleared.
168 if (size_policy() != NULL) {
169 _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near();
170 }
171 _all_soft_refs_clear = true;
172 }
174 size_t CollectorPolicy::compute_heap_alignment() {
175 // The card marking array and the offset arrays for old generations are
176 // committed in os pages as well. Make sure they are entirely full (to
177 // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
178 // byte entry and the os page size is 4096, the maximum heap size should
179 // be 512*4096 = 2MB aligned.
181 // There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable
182 // is supported.
183 // Requirements of any new remembered set implementations must be added here.
184 size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
186 // Parallel GC does its own alignment of the generations to avoid requiring a
187 // large page (256M on some platforms) for the permanent generation. The
188 // other collectors should also be updated to do their own alignment and then
189 // this use of lcm() should be removed.
190 if (UseLargePages && !UseParallelGC) {
191 // in presence of large pages we have to make sure that our
192 // alignment is large page aware
193 alignment = lcm(os::large_page_size(), alignment);
194 }
196 return alignment;
197 }
199 // GenCollectorPolicy methods.
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 {}
209 size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
210 return align_size_down_bounded(base_size / (NewRatio + 1), _gen_alignment);
211 }
213 size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
214 size_t maximum_size) {
215 size_t max_minus = maximum_size - _gen_alignment;
216 return desired_size < max_minus ? desired_size : max_minus;
217 }
220 void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
221 size_t init_promo_size,
222 size_t init_survivor_size) {
223 const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
224 _size_policy = new AdaptiveSizePolicy(init_eden_size,
225 init_promo_size,
226 init_survivor_size,
227 max_gc_pause_sec,
228 GCTimeRatio);
229 }
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 }
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 }
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 }
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 }
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
276 void GenCollectorPolicy::initialize_flags() {
277 CollectorPolicy::initialize_flags();
279 assert(_gen_alignment != 0, "Generation alignment not set up properly");
280 assert(_heap_alignment >= _gen_alignment,
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));
290 // All generational heaps have a youngest gen; handle those flags here
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 }
309 // Now take the actual NewSize into account. We will silently increase NewSize
310 // if the user specified a smaller or unaligned value.
311 smallest_new_size = MAX2(smallest_new_size, (uintx)align_size_down(NewSize, _gen_alignment));
312 if (smallest_new_size != NewSize) {
313 // Do not use FLAG_SET_ERGO to update NewSize here, since this will override
314 // if NewSize was set on the command line or not. This information is needed
315 // later when setting the initial and minimum young generation size.
316 NewSize = smallest_new_size;
317 }
318 _initial_gen0_size = NewSize;
320 if (!FLAG_IS_DEFAULT(MaxNewSize)) {
321 uintx min_new_size = MAX2(_gen_alignment, _min_gen0_size);
323 if (MaxNewSize >= MaxHeapSize) {
324 // Make sure there is room for an old generation
325 uintx smaller_max_new_size = MaxHeapSize - _gen_alignment;
326 if (FLAG_IS_CMDLINE(MaxNewSize)) {
327 warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "
328 "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.",
329 MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);
330 }
331 FLAG_SET_ERGO(uintx, MaxNewSize, smaller_max_new_size);
332 if (NewSize > MaxNewSize) {
333 FLAG_SET_ERGO(uintx, NewSize, MaxNewSize);
334 _initial_gen0_size = NewSize;
335 }
336 } else if (MaxNewSize < min_new_size) {
337 FLAG_SET_ERGO(uintx, MaxNewSize, min_new_size);
338 } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) {
339 FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));
340 }
341 _max_gen0_size = MaxNewSize;
342 }
344 if (NewSize > MaxNewSize) {
345 // At this point this should only happen if the user specifies a large NewSize and/or
346 // a small (but not too small) MaxNewSize.
347 if (FLAG_IS_CMDLINE(MaxNewSize)) {
348 warning("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
349 "A new max generation size of " SIZE_FORMAT "k will be used.",
350 NewSize/K, MaxNewSize/K, NewSize/K);
351 }
352 FLAG_SET_ERGO(uintx, MaxNewSize, NewSize);
353 _max_gen0_size = MaxNewSize;
354 }
356 if (SurvivorRatio < 1 || NewRatio < 1) {
357 vm_exit_during_initialization("Invalid young gen ratio specified");
358 }
360 DEBUG_ONLY(GenCollectorPolicy::assert_flags();)
361 }
363 void TwoGenerationCollectorPolicy::initialize_flags() {
364 GenCollectorPolicy::initialize_flags();
366 if (!is_size_aligned(OldSize, _gen_alignment)) {
367 FLAG_SET_ERGO(uintx, OldSize, align_size_down(OldSize, _gen_alignment));
368 }
370 if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {
371 // NewRatio will be used later to set the young generation size so we use
372 // it to calculate how big the heap should be based on the requested OldSize
373 // and NewRatio.
374 assert(NewRatio > 0, "NewRatio should have been set up earlier");
375 size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
377 calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment);
378 FLAG_SET_ERGO(uintx, MaxHeapSize, calculated_heapsize);
379 _max_heap_byte_size = MaxHeapSize;
380 FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize);
381 _initial_heap_byte_size = InitialHeapSize;
382 }
384 // adjust max heap size if necessary
385 if (NewSize + OldSize > MaxHeapSize) {
386 if (_max_heap_size_cmdline) {
387 // somebody set a maximum heap size with the intention that we should not
388 // exceed it. Adjust New/OldSize as necessary.
389 uintx calculated_size = NewSize + OldSize;
390 double shrink_factor = (double) MaxHeapSize / calculated_size;
391 uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment);
392 FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
393 _initial_gen0_size = NewSize;
395 // OldSize is already aligned because above we aligned MaxHeapSize to
396 // _heap_alignment, and we just made sure that NewSize is aligned to
397 // _gen_alignment. In initialize_flags() we verified that _heap_alignment
398 // is a multiple of _gen_alignment.
399 FLAG_SET_ERGO(uintx, OldSize, MaxHeapSize - NewSize);
400 } else {
401 FLAG_SET_ERGO(uintx, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
402 _max_heap_byte_size = MaxHeapSize;
403 }
404 }
406 always_do_update_barrier = UseConcMarkSweepGC;
408 DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_flags();)
409 }
411 // Values set on the command line win over any ergonomically
412 // set command line parameters.
413 // Ergonomic choice of parameters are done before this
414 // method is called. Values for command line parameters such as NewSize
415 // and MaxNewSize feed those ergonomic choices into this method.
416 // This method makes the final generation sizings consistent with
417 // themselves and with overall heap sizings.
418 // In the absence of explicitly set command line flags, policies
419 // such as the use of NewRatio are used to size the generation.
420 void GenCollectorPolicy::initialize_size_info() {
421 CollectorPolicy::initialize_size_info();
423 // _space_alignment is used for alignment within a generation.
424 // There is additional alignment done down stream for some
425 // collectors that sometimes causes unwanted rounding up of
426 // generations sizes.
428 // Determine maximum size of gen0
430 size_t max_new_size = 0;
431 if (!FLAG_IS_DEFAULT(MaxNewSize)) {
432 max_new_size = MaxNewSize;
433 } else {
434 max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size);
435 // Bound the maximum size by NewSize below (since it historically
436 // would have been NewSize and because the NewRatio calculation could
437 // yield a size that is too small) and bound it by MaxNewSize above.
438 // Ergonomics plays here by previously calculating the desired
439 // NewSize and MaxNewSize.
440 max_new_size = MIN2(MAX2(max_new_size, NewSize), MaxNewSize);
441 }
442 assert(max_new_size > 0, "All paths should set max_new_size");
444 // Given the maximum gen0 size, determine the initial and
445 // minimum gen0 sizes.
447 if (_max_heap_byte_size == _min_heap_byte_size) {
448 // The maximum and minimum heap sizes are the same so
449 // the generations minimum and initial must be the
450 // same as its maximum.
451 _min_gen0_size = max_new_size;
452 _initial_gen0_size = max_new_size;
453 _max_gen0_size = max_new_size;
454 } else {
455 size_t desired_new_size = 0;
456 if (FLAG_IS_CMDLINE(NewSize)) {
457 // If NewSize is set on the command line, we must use it as
458 // the initial size and it also makes sense to use it as the
459 // lower limit.
460 _min_gen0_size = NewSize;
461 desired_new_size = NewSize;
462 max_new_size = MAX2(max_new_size, NewSize);
463 } else if (FLAG_IS_ERGO(NewSize)) {
464 // If NewSize is set ergonomically, we should use it as a lower
465 // limit, but use NewRatio to calculate the initial size.
466 _min_gen0_size = NewSize;
467 desired_new_size =
468 MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);
469 max_new_size = MAX2(max_new_size, NewSize);
470 } else {
471 // For the case where NewSize is the default, use NewRatio
472 // to size the minimum and initial generation sizes.
473 // Use the default NewSize as the floor for these values. If
474 // NewRatio is overly large, the resulting sizes can be too
475 // small.
476 _min_gen0_size = MAX2(scale_by_NewRatio_aligned(_min_heap_byte_size), NewSize);
477 desired_new_size =
478 MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);
479 }
481 assert(_min_gen0_size > 0, "Sanity check");
482 _initial_gen0_size = desired_new_size;
483 _max_gen0_size = max_new_size;
485 // At this point the desirable initial and minimum sizes have been
486 // determined without regard to the maximum sizes.
488 // Bound the sizes by the corresponding overall heap sizes.
489 _min_gen0_size = bound_minus_alignment(_min_gen0_size, _min_heap_byte_size);
490 _initial_gen0_size = bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size);
491 _max_gen0_size = bound_minus_alignment(_max_gen0_size, _max_heap_byte_size);
493 // At this point all three sizes have been checked against the
494 // maximum sizes but have not been checked for consistency
495 // among the three.
497 // Final check min <= initial <= max
498 _min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size);
499 _initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size);
500 _min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size);
501 }
503 // Write back to flags if necessary
504 if (NewSize != _initial_gen0_size) {
505 FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size);
506 }
508 if (MaxNewSize != _max_gen0_size) {
509 FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size);
510 }
512 if (PrintGCDetails && Verbose) {
513 gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
514 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
515 _min_gen0_size, _initial_gen0_size, _max_gen0_size);
516 }
518 DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
519 }
521 // Call this method during the sizing of the gen1 to make
522 // adjustments to gen0 because of gen1 sizing policy. gen0 initially has
523 // the most freedom in sizing because it is done before the
524 // policy for gen1 is applied. Once gen1 policies have been applied,
525 // there may be conflicts in the shape of the heap and this method
526 // is used to make the needed adjustments. The application of the
527 // policies could be more sophisticated (iterative for example) but
528 // keeping it simple also seems a worthwhile goal.
529 bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr,
530 size_t* gen1_size_ptr,
531 const size_t heap_size) {
532 bool result = false;
534 if ((*gen0_size_ptr + *gen1_size_ptr) > heap_size) {
535 uintx smallest_new_size = young_gen_size_lower_bound();
536 if ((heap_size < (*gen0_size_ptr + _min_gen1_size)) &&
537 (heap_size >= _min_gen1_size + smallest_new_size)) {
538 // Adjust gen0 down to accommodate _min_gen1_size
539 *gen0_size_ptr = align_size_down_bounded(heap_size - _min_gen1_size, _gen_alignment);
540 result = true;
541 } else {
542 *gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _gen_alignment);
543 }
544 }
545 return result;
546 }
548 // Minimum sizes of the generations may be different than
549 // the initial sizes. An inconsistently is permitted here
550 // in the total size that can be specified explicitly by
551 // command line specification of OldSize and NewSize and
552 // also a command line specification of -Xms. Issue a warning
553 // but allow the values to pass.
555 void TwoGenerationCollectorPolicy::initialize_size_info() {
556 GenCollectorPolicy::initialize_size_info();
558 // At this point the minimum, initial and maximum sizes
559 // of the overall heap and of gen0 have been determined.
560 // The maximum gen1 size can be determined from the maximum gen0
561 // and maximum heap size since no explicit flags exits
562 // for setting the gen1 maximum.
563 _max_gen1_size = MAX2(_max_heap_byte_size - _max_gen0_size, _gen_alignment);
565 // If no explicit command line flag has been set for the
566 // gen1 size, use what is left for gen1.
567 if (!FLAG_IS_CMDLINE(OldSize)) {
568 // The user has not specified any value but the ergonomics
569 // may have chosen a value (which may or may not be consistent
570 // with the overall heap size). In either case make
571 // the minimum, maximum and initial sizes consistent
572 // with the gen0 sizes and the overall heap sizes.
573 _min_gen1_size = MAX2(_min_heap_byte_size - _min_gen0_size, _gen_alignment);
574 _initial_gen1_size = MAX2(_initial_heap_byte_size - _initial_gen0_size, _gen_alignment);
575 // _max_gen1_size has already been made consistent above
576 FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);
577 } else {
578 // It's been explicitly set on the command line. Use the
579 // OldSize and then determine the consequences.
580 _min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size);
581 _initial_gen1_size = OldSize;
583 // If the user has explicitly set an OldSize that is inconsistent
584 // with other command line flags, issue a warning.
585 // The generation minimums and the overall heap mimimum should
586 // be within one generation alignment.
587 if ((_min_gen1_size + _min_gen0_size + _gen_alignment) < _min_heap_byte_size) {
588 warning("Inconsistency between minimum heap size and minimum "
589 "generation sizes: using minimum heap = " SIZE_FORMAT,
590 _min_heap_byte_size);
591 }
592 if (OldSize > _max_gen1_size) {
593 warning("Inconsistency between maximum heap size and maximum "
594 "generation sizes: using maximum heap = " SIZE_FORMAT
595 " -XX:OldSize flag is being ignored",
596 _max_heap_byte_size);
597 }
598 // If there is an inconsistency between the OldSize and the minimum and/or
599 // initial size of gen0, since OldSize was explicitly set, OldSize wins.
600 if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size, _min_heap_byte_size)) {
601 if (PrintGCDetails && Verbose) {
602 gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
603 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
604 _min_gen0_size, _initial_gen0_size, _max_gen0_size);
605 }
606 }
607 // Initial size
608 if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
609 _initial_heap_byte_size)) {
610 if (PrintGCDetails && Verbose) {
611 gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
612 SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
613 _min_gen0_size, _initial_gen0_size, _max_gen0_size);
614 }
615 }
616 }
617 // Enforce the maximum gen1 size.
618 _min_gen1_size = MIN2(_min_gen1_size, _max_gen1_size);
620 // Check that min gen1 <= initial gen1 <= max gen1
621 _initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size);
622 _initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size);
624 // Write back to flags if necessary
625 if (NewSize != _initial_gen0_size) {
626 FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size);
627 }
629 if (MaxNewSize != _max_gen0_size) {
630 FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size);
631 }
633 if (OldSize != _initial_gen1_size) {
634 FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);
635 }
637 if (PrintGCDetails && Verbose) {
638 gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 "
639 SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT,
640 _min_gen1_size, _initial_gen1_size, _max_gen1_size);
641 }
643 DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_size_info();)
644 }
646 HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
647 bool is_tlab,
648 bool* gc_overhead_limit_was_exceeded) {
649 GenCollectedHeap *gch = GenCollectedHeap::heap();
651 debug_only(gch->check_for_valid_allocation_state());
652 assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
654 // In general gc_overhead_limit_was_exceeded should be false so
655 // set it so here and reset it to true only if the gc time
656 // limit is being exceeded as checked below.
657 *gc_overhead_limit_was_exceeded = false;
659 HeapWord* result = NULL;
661 // Loop until the allocation is satisified,
662 // or unsatisfied after GC.
663 for (int try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
664 HandleMark hm; // discard any handles allocated in each iteration
666 // First allocation attempt is lock-free.
667 Generation *gen0 = gch->get_gen(0);
668 assert(gen0->supports_inline_contig_alloc(),
669 "Otherwise, must do alloc within heap lock");
670 if (gen0->should_allocate(size, is_tlab)) {
671 result = gen0->par_allocate(size, is_tlab);
672 if (result != NULL) {
673 assert(gch->is_in_reserved(result), "result not in heap");
674 return result;
675 }
676 }
677 unsigned int gc_count_before; // read inside the Heap_lock locked region
678 {
679 MutexLocker ml(Heap_lock);
680 if (PrintGC && Verbose) {
681 gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"
682 " attempting locked slow path allocation");
683 }
684 // Note that only large objects get a shot at being
685 // allocated in later generations.
686 bool first_only = ! should_try_older_generation_allocation(size);
688 result = gch->attempt_allocation(size, is_tlab, first_only);
689 if (result != NULL) {
690 assert(gch->is_in_reserved(result), "result not in heap");
691 return result;
692 }
694 if (GC_locker::is_active_and_needs_gc()) {
695 if (is_tlab) {
696 return NULL; // Caller will retry allocating individual object
697 }
698 if (!gch->is_maximal_no_gc()) {
699 // Try and expand heap to satisfy request
700 result = expand_heap_and_allocate(size, is_tlab);
701 // result could be null if we are out of space
702 if (result != NULL) {
703 return result;
704 }
705 }
707 if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
708 return NULL; // we didn't get to do a GC and we didn't get any memory
709 }
711 // If this thread is not in a jni critical section, we stall
712 // the requestor until the critical section has cleared and
713 // GC allowed. When the critical section clears, a GC is
714 // initiated by the last thread exiting the critical section; so
715 // we retry the allocation sequence from the beginning of the loop,
716 // rather than causing more, now probably unnecessary, GC attempts.
717 JavaThread* jthr = JavaThread::current();
718 if (!jthr->in_critical()) {
719 MutexUnlocker mul(Heap_lock);
720 // Wait for JNI critical section to be exited
721 GC_locker::stall_until_clear();
722 gclocker_stalled_count += 1;
723 continue;
724 } else {
725 if (CheckJNICalls) {
726 fatal("Possible deadlock due to allocating while"
727 " in jni critical section");
728 }
729 return NULL;
730 }
731 }
733 // Read the gc count while the heap lock is held.
734 gc_count_before = Universe::heap()->total_collections();
735 }
737 VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
738 VMThread::execute(&op);
739 if (op.prologue_succeeded()) {
740 result = op.result();
741 if (op.gc_locked()) {
742 assert(result == NULL, "must be NULL if gc_locked() is true");
743 continue; // retry and/or stall as necessary
744 }
746 // Allocation has failed and a collection
747 // has been done. If the gc time limit was exceeded the
748 // this time, return NULL so that an out-of-memory
749 // will be thrown. Clear gc_overhead_limit_exceeded
750 // so that the overhead exceeded does not persist.
752 const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
753 const bool softrefs_clear = all_soft_refs_clear();
755 if (limit_exceeded && softrefs_clear) {
756 *gc_overhead_limit_was_exceeded = true;
757 size_policy()->set_gc_overhead_limit_exceeded(false);
758 if (op.result() != NULL) {
759 CollectedHeap::fill_with_object(op.result(), size);
760 }
761 return NULL;
762 }
763 assert(result == NULL || gch->is_in_reserved(result),
764 "result not in heap");
765 return result;
766 }
768 // Give a warning if we seem to be looping forever.
769 if ((QueuedAllocationWarningCount > 0) &&
770 (try_count % QueuedAllocationWarningCount == 0)) {
771 warning("TwoGenerationCollectorPolicy::mem_allocate_work retries %d times \n\t"
772 " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
773 }
774 }
775 }
777 HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size,
778 bool is_tlab) {
779 GenCollectedHeap *gch = GenCollectedHeap::heap();
780 HeapWord* result = NULL;
781 for (int i = number_of_generations() - 1; i >= 0 && result == NULL; i--) {
782 Generation *gen = gch->get_gen(i);
783 if (gen->should_allocate(size, is_tlab)) {
784 result = gen->expand_and_allocate(size, is_tlab);
785 }
786 }
787 assert(result == NULL || gch->is_in_reserved(result), "result not in heap");
788 return result;
789 }
791 HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
792 bool is_tlab) {
793 GenCollectedHeap *gch = GenCollectedHeap::heap();
794 GCCauseSetter x(gch, GCCause::_allocation_failure);
795 HeapWord* result = NULL;
797 assert(size != 0, "Precondition violated");
798 if (GC_locker::is_active_and_needs_gc()) {
799 // GC locker is active; instead of a collection we will attempt
800 // to expand the heap, if there's room for expansion.
801 if (!gch->is_maximal_no_gc()) {
802 result = expand_heap_and_allocate(size, is_tlab);
803 }
804 return result; // could be null if we are out of space
805 } else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) {
806 // Do an incremental collection.
807 gch->do_collection(false /* full */,
808 false /* clear_all_soft_refs */,
809 size /* size */,
810 is_tlab /* is_tlab */,
811 number_of_generations() - 1 /* max_level */);
812 } else {
813 if (Verbose && PrintGCDetails) {
814 gclog_or_tty->print(" :: Trying full because partial may fail :: ");
815 }
816 // Try a full collection; see delta for bug id 6266275
817 // for the original code and why this has been simplified
818 // with from-space allocation criteria modified and
819 // such allocation moved out of the safepoint path.
820 gch->do_collection(true /* full */,
821 false /* clear_all_soft_refs */,
822 size /* size */,
823 is_tlab /* is_tlab */,
824 number_of_generations() - 1 /* max_level */);
825 }
827 result = gch->attempt_allocation(size, is_tlab, false /*first_only*/);
829 if (result != NULL) {
830 assert(gch->is_in_reserved(result), "result not in heap");
831 return result;
832 }
834 // OK, collection failed, try expansion.
835 result = expand_heap_and_allocate(size, is_tlab);
836 if (result != NULL) {
837 return result;
838 }
840 // If we reach this point, we're really out of memory. Try every trick
841 // we can to reclaim memory. Force collection of soft references. Force
842 // a complete compaction of the heap. Any additional methods for finding
843 // free memory should be here, especially if they are expensive. If this
844 // attempt fails, an OOM exception will be thrown.
845 {
846 UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
848 gch->do_collection(true /* full */,
849 true /* clear_all_soft_refs */,
850 size /* size */,
851 is_tlab /* is_tlab */,
852 number_of_generations() - 1 /* max_level */);
853 }
855 result = gch->attempt_allocation(size, is_tlab, false /* first_only */);
856 if (result != NULL) {
857 assert(gch->is_in_reserved(result), "result not in heap");
858 return result;
859 }
861 assert(!should_clear_all_soft_refs(),
862 "Flag should have been handled and cleared prior to this point");
864 // What else? We might try synchronous finalization later. If the total
865 // space available is large enough for the allocation, then a more
866 // complete compaction phase than we've tried so far might be
867 // appropriate.
868 return NULL;
869 }
871 MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
872 ClassLoaderData* loader_data,
873 size_t word_size,
874 Metaspace::MetadataType mdtype) {
875 uint loop_count = 0;
876 uint gc_count = 0;
877 uint full_gc_count = 0;
879 assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
881 do {
882 MetaWord* result = NULL;
883 if (GC_locker::is_active_and_needs_gc()) {
884 // If the GC_locker is active, just expand and allocate.
885 // If that does not succeed, wait if this thread is not
886 // in a critical section itself.
887 result =
888 loader_data->metaspace_non_null()->expand_and_allocate(word_size,
889 mdtype);
890 if (result != NULL) {
891 return result;
892 }
893 JavaThread* jthr = JavaThread::current();
894 if (!jthr->in_critical()) {
895 // Wait for JNI critical section to be exited
896 GC_locker::stall_until_clear();
897 // The GC invoked by the last thread leaving the critical
898 // section will be a young collection and a full collection
899 // is (currently) needed for unloading classes so continue
900 // to the next iteration to get a full GC.
901 continue;
902 } else {
903 if (CheckJNICalls) {
904 fatal("Possible deadlock due to allocating while"
905 " in jni critical section");
906 }
907 return NULL;
908 }
909 }
911 { // Need lock to get self consistent gc_count's
912 MutexLocker ml(Heap_lock);
913 gc_count = Universe::heap()->total_collections();
914 full_gc_count = Universe::heap()->total_full_collections();
915 }
917 // Generate a VM operation
918 VM_CollectForMetadataAllocation op(loader_data,
919 word_size,
920 mdtype,
921 gc_count,
922 full_gc_count,
923 GCCause::_metadata_GC_threshold);
924 VMThread::execute(&op);
926 // If GC was locked out, try again. Check
927 // before checking success because the prologue
928 // could have succeeded and the GC still have
929 // been locked out.
930 if (op.gc_locked()) {
931 continue;
932 }
934 if (op.prologue_succeeded()) {
935 return op.result();
936 }
937 loop_count++;
938 if ((QueuedAllocationWarningCount > 0) &&
939 (loop_count % QueuedAllocationWarningCount == 0)) {
940 warning("satisfy_failed_metadata_allocation() retries %d times \n\t"
941 " size=" SIZE_FORMAT, loop_count, word_size);
942 }
943 } while (true); // Until a GC is done
944 }
946 // Return true if any of the following is true:
947 // . the allocation won't fit into the current young gen heap
948 // . gc locker is occupied (jni critical section)
949 // . heap memory is tight -- the most recent previous collection
950 // was a full collection because a partial collection (would
951 // have) failed and is likely to fail again
952 bool GenCollectorPolicy::should_try_older_generation_allocation(
953 size_t word_size) const {
954 GenCollectedHeap* gch = GenCollectedHeap::heap();
955 size_t gen0_capacity = gch->get_gen(0)->capacity_before_gc();
956 return (word_size > heap_word_size(gen0_capacity))
957 || GC_locker::is_active_and_needs_gc()
958 || gch->incremental_collection_failed();
959 }
962 //
963 // MarkSweepPolicy methods
964 //
966 void MarkSweepPolicy::initialize_alignments() {
967 _space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
968 _heap_alignment = compute_heap_alignment();
969 }
971 void MarkSweepPolicy::initialize_generations() {
972 _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
973 if (_generations == NULL) {
974 vm_exit_during_initialization("Unable to allocate gen spec");
975 }
977 if (UseParNewGC) {
978 _generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size);
979 } else {
980 _generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size);
981 }
982 _generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_gen1_size, _max_gen1_size);
984 if (_generations[0] == NULL || _generations[1] == NULL) {
985 vm_exit_during_initialization("Unable to allocate gen spec");
986 }
987 }
989 void MarkSweepPolicy::initialize_gc_policy_counters() {
990 // initialize the policy counters - 2 collectors, 3 generations
991 if (UseParNewGC) {
992 _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3);
993 } else {
994 _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
995 }
996 }
998 /////////////// Unit tests ///////////////
1000 #ifndef PRODUCT
1001 // Testing that the NewSize flag is handled correct is hard because it
1002 // depends on so many other configurable variables. This test only tries to
1003 // verify that there are some basic rules for NewSize honored by the policies.
1004 class TestGenCollectorPolicy {
1005 public:
1006 static void test() {
1007 size_t flag_value;
1009 save_flags();
1011 // Set some limits that makes the math simple.
1012 FLAG_SET_ERGO(uintx, MaxHeapSize, 180 * M);
1013 FLAG_SET_ERGO(uintx, InitialHeapSize, 120 * M);
1014 Arguments::set_min_heap_size(40 * M);
1016 // If NewSize is set on the command line, it should be used
1017 // for both min and initial young size if less than min heap.
1018 flag_value = 20 * M;
1019 FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
1020 verify_min(flag_value);
1021 verify_initial(flag_value);
1023 // If NewSize is set on command line, but is larger than the min
1024 // heap size, it should only be used for initial young size.
1025 flag_value = 80 * M;
1026 FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
1027 verify_initial(flag_value);
1029 // If NewSize has been ergonomically set, the collector policy
1030 // should use it for min but calculate the initial young size
1031 // using NewRatio.
1032 flag_value = 20 * M;
1033 FLAG_SET_ERGO(uintx, NewSize, flag_value);
1034 verify_min(flag_value);
1035 verify_scaled_initial(InitialHeapSize);
1037 restore_flags();
1039 }
1041 static void verify_min(size_t expected) {
1042 MarkSweepPolicy msp;
1043 msp.initialize_all();
1045 assert(msp.min_gen0_size() <= expected, err_msg("%zu > %zu", msp.min_gen0_size(), expected));
1046 }
1048 static void verify_initial(size_t expected) {
1049 MarkSweepPolicy msp;
1050 msp.initialize_all();
1052 assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected));
1053 }
1055 static void verify_scaled_initial(size_t initial_heap_size) {
1056 MarkSweepPolicy msp;
1057 msp.initialize_all();
1059 size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size);
1060 assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected));
1061 assert(FLAG_IS_ERGO(NewSize) && NewSize == expected,
1062 err_msg("NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize));
1063 }
1065 private:
1066 static size_t original_InitialHeapSize;
1067 static size_t original_MaxHeapSize;
1068 static size_t original_MaxNewSize;
1069 static size_t original_MinHeapDeltaBytes;
1070 static size_t original_NewSize;
1071 static size_t original_OldSize;
1073 static void save_flags() {
1074 original_InitialHeapSize = InitialHeapSize;
1075 original_MaxHeapSize = MaxHeapSize;
1076 original_MaxNewSize = MaxNewSize;
1077 original_MinHeapDeltaBytes = MinHeapDeltaBytes;
1078 original_NewSize = NewSize;
1079 original_OldSize = OldSize;
1080 }
1082 static void restore_flags() {
1083 InitialHeapSize = original_InitialHeapSize;
1084 MaxHeapSize = original_MaxHeapSize;
1085 MaxNewSize = original_MaxNewSize;
1086 MinHeapDeltaBytes = original_MinHeapDeltaBytes;
1087 NewSize = original_NewSize;
1088 OldSize = original_OldSize;
1089 }
1090 };
1092 size_t TestGenCollectorPolicy::original_InitialHeapSize = 0;
1093 size_t TestGenCollectorPolicy::original_MaxHeapSize = 0;
1094 size_t TestGenCollectorPolicy::original_MaxNewSize = 0;
1095 size_t TestGenCollectorPolicy::original_MinHeapDeltaBytes = 0;
1096 size_t TestGenCollectorPolicy::original_NewSize = 0;
1097 size_t TestGenCollectorPolicy::original_OldSize = 0;
1099 void TestNewSize_test() {
1100 TestGenCollectorPolicy::test();
1101 }
1103 #endif