collectorPolicy.cpp revision 11608:2cd9adeec880
1/*
2 * Copyright (c) 2001, 2016, 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 */
24
25#include "precompiled.hpp"
26#include "gc/shared/adaptiveSizePolicy.hpp"
27#include "gc/shared/cardTableRS.hpp"
28#include "gc/shared/collectorPolicy.hpp"
29#include "gc/shared/gcLocker.inline.hpp"
30#include "gc/shared/gcPolicyCounters.hpp"
31#include "gc/shared/genCollectedHeap.hpp"
32#include "gc/shared/generationSpec.hpp"
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
47CollectorPolicy::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
60void 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
66void 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");
74  assert(_max_heap_byte_size % _heap_alignment == 0, "max_heap_byte_size alignment");
75}
76#endif // ASSERT
77
78void 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) {
116    FLAG_SET_ERGO(size_t, InitialHeapSize, aligned_initial_heap_size);
117  }
118  if (aligned_max_heap_size != MaxHeapSize) {
119    FLAG_SET_ERGO(size_t, MaxHeapSize, aligned_max_heap_size);
120  }
121
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(size_t, MaxHeapSize, InitialHeapSize);
128  } else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {
129    FLAG_SET_ERGO(size_t, 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(size_t, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));
139
140  DEBUG_ONLY(CollectorPolicy::assert_flags();)
141}
142
143void CollectorPolicy::initialize_size_info() {
144  log_debug(gc, heap)("Minimum heap " SIZE_FORMAT "  Initial heap " SIZE_FORMAT "  Maximum heap " SIZE_FORMAT,
145                      _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
146
147  DEBUG_ONLY(CollectorPolicy::assert_size_info();)
148}
149
150bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
151  bool result = _should_clear_all_soft_refs;
152  set_should_clear_all_soft_refs(false);
153  return result;
154}
155
156CardTableRS* CollectorPolicy::create_rem_set(MemRegion whole_heap) {
157  return new CardTableRS(whole_heap);
158}
159
160void CollectorPolicy::cleared_all_soft_refs() {
161  // If near gc overhear limit, continue to clear SoftRefs.  SoftRefs may
162  // have been cleared in the last collection but if the gc overhear
163  // limit continues to be near, SoftRefs should still be cleared.
164  if (size_policy() != NULL) {
165    _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near();
166  }
167  _all_soft_refs_clear = true;
168}
169
170size_t CollectorPolicy::compute_heap_alignment() {
171  // The card marking array and the offset arrays for old generations are
172  // committed in os pages as well. Make sure they are entirely full (to
173  // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
174  // byte entry and the os page size is 4096, the maximum heap size should
175  // be 512*4096 = 2MB aligned.
176
177  size_t alignment = CardTableRS::ct_max_alignment_constraint();
178
179  if (UseLargePages) {
180      // In presence of large pages we have to make sure that our
181      // alignment is large page aware.
182      alignment = lcm(os::large_page_size(), alignment);
183  }
184
185  return alignment;
186}
187
188// GenCollectorPolicy methods
189
190GenCollectorPolicy::GenCollectorPolicy() :
191    _min_young_size(0),
192    _initial_young_size(0),
193    _max_young_size(0),
194    _min_old_size(0),
195    _initial_old_size(0),
196    _max_old_size(0),
197    _gen_alignment(0),
198    _young_gen_spec(NULL),
199    _old_gen_spec(NULL)
200{}
201
202size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
203  return align_size_down_bounded(base_size / (NewRatio + 1), _gen_alignment);
204}
205
206size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
207                                                 size_t maximum_size) {
208  size_t max_minus = maximum_size - _gen_alignment;
209  return desired_size < max_minus ? desired_size : max_minus;
210}
211
212
213void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
214                                                size_t init_promo_size,
215                                                size_t init_survivor_size) {
216  const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
217  _size_policy = new AdaptiveSizePolicy(init_eden_size,
218                                        init_promo_size,
219                                        init_survivor_size,
220                                        max_gc_pause_sec,
221                                        GCTimeRatio);
222}
223
224size_t GenCollectorPolicy::young_gen_size_lower_bound() {
225  // The young generation must be aligned and have room for eden + two survivors
226  return align_size_up(3 * _space_alignment, _gen_alignment);
227}
228
229size_t GenCollectorPolicy::old_gen_size_lower_bound() {
230  return align_size_up(_space_alignment, _gen_alignment);
231}
232
233#ifdef ASSERT
234void GenCollectorPolicy::assert_flags() {
235  CollectorPolicy::assert_flags();
236  assert(NewSize >= _min_young_size, "Ergonomics decided on a too small young gen size");
237  assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes");
238  assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes");
239  assert(NewSize % _gen_alignment == 0, "NewSize alignment");
240  assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % _gen_alignment == 0, "MaxNewSize alignment");
241  assert(OldSize + NewSize <= MaxHeapSize, "Ergonomics decided on incompatible generation and heap sizes");
242  assert(OldSize % _gen_alignment == 0, "OldSize alignment");
243}
244
245void GenCollectorPolicy::assert_size_info() {
246  CollectorPolicy::assert_size_info();
247  // GenCollectorPolicy::initialize_size_info may update the MaxNewSize
248  assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes");
249  assert(NewSize == _initial_young_size, "Discrepancy between NewSize flag and local storage");
250  assert(MaxNewSize == _max_young_size, "Discrepancy between MaxNewSize flag and local storage");
251  assert(OldSize == _initial_old_size, "Discrepancy between OldSize flag and local storage");
252  assert(_min_young_size <= _initial_young_size, "Ergonomics decided on incompatible minimum and initial young gen sizes");
253  assert(_initial_young_size <= _max_young_size, "Ergonomics decided on incompatible initial and maximum young gen sizes");
254  assert(_min_young_size % _gen_alignment == 0, "_min_young_size alignment");
255  assert(_initial_young_size % _gen_alignment == 0, "_initial_young_size alignment");
256  assert(_max_young_size % _gen_alignment == 0, "_max_young_size alignment");
257  assert(_min_young_size <= bound_minus_alignment(_min_young_size, _min_heap_byte_size),
258      "Ergonomics made minimum young generation larger than minimum heap");
259  assert(_initial_young_size <=  bound_minus_alignment(_initial_young_size, _initial_heap_byte_size),
260      "Ergonomics made initial young generation larger than initial heap");
261  assert(_max_young_size <= bound_minus_alignment(_max_young_size, _max_heap_byte_size),
262      "Ergonomics made maximum young generation lager than maximum heap");
263  assert(_min_old_size <= _initial_old_size, "Ergonomics decided on incompatible minimum and initial old gen sizes");
264  assert(_initial_old_size <= _max_old_size, "Ergonomics decided on incompatible initial and maximum old gen sizes");
265  assert(_max_old_size % _gen_alignment == 0, "_max_old_size alignment");
266  assert(_initial_old_size % _gen_alignment == 0, "_initial_old_size alignment");
267  assert(_max_heap_byte_size <= (_max_young_size + _max_old_size), "Total maximum heap sizes must be sum of generation maximum sizes");
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
274void 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);
342    } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) {
343      FLAG_SET_ERGO(size_t, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));
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
408  // OldSize is set on the command line.
409  if (FLAG_IS_CMDLINE(OldSize) && !FLAG_IS_CMDLINE(NewSize)) {
410    if (OldSize < _initial_heap_byte_size) {
411      size_t new_size = _initial_heap_byte_size - OldSize;
412      // Need to compare against the flag value for max since _max_young_size
413      // might not have been set yet.
414      if (new_size >= _min_young_size && new_size <= MaxNewSize) {
415        FLAG_SET_ERGO(size_t, NewSize, new_size);
416        _initial_young_size = NewSize;
417      }
418    }
419  }
420
421  always_do_update_barrier = UseConcMarkSweepGC;
422
423  DEBUG_ONLY(GenCollectorPolicy::assert_flags();)
424}
425
426// Values set on the command line win over any ergonomically
427// set command line parameters.
428// Ergonomic choice of parameters are done before this
429// method is called.  Values for command line parameters such as NewSize
430// and MaxNewSize feed those ergonomic choices into this method.
431// This method makes the final generation sizings consistent with
432// themselves and with overall heap sizings.
433// In the absence of explicitly set command line flags, policies
434// such as the use of NewRatio are used to size the generation.
435
436// Minimum sizes of the generations may be different than
437// the initial sizes.  An inconsistency is permitted here
438// in the total size that can be specified explicitly by
439// command line specification of OldSize and NewSize and
440// also a command line specification of -Xms.  Issue a warning
441// but allow the values to pass.
442void GenCollectorPolicy::initialize_size_info() {
443  CollectorPolicy::initialize_size_info();
444
445  _initial_young_size = NewSize;
446  _max_young_size = MaxNewSize;
447  _initial_old_size = OldSize;
448
449  // Determine maximum size of the young generation.
450
451  if (FLAG_IS_DEFAULT(MaxNewSize)) {
452    _max_young_size = scale_by_NewRatio_aligned(_max_heap_byte_size);
453    // Bound the maximum size by NewSize below (since it historically
454    // would have been NewSize and because the NewRatio calculation could
455    // yield a size that is too small) and bound it by MaxNewSize above.
456    // Ergonomics plays here by previously calculating the desired
457    // NewSize and MaxNewSize.
458    _max_young_size = MIN2(MAX2(_max_young_size, _initial_young_size), MaxNewSize);
459  }
460
461  // Given the maximum young size, determine the initial and
462  // minimum young sizes.
463
464  if (_max_heap_byte_size == _initial_heap_byte_size) {
465    // The maximum and initial heap sizes are the same so the generation's
466    // initial size must be the same as it maximum size. Use NewSize as the
467    // size if set on command line.
468    _max_young_size = FLAG_IS_CMDLINE(NewSize) ? NewSize : _max_young_size;
469    _initial_young_size = _max_young_size;
470
471    // Also update the minimum size if min == initial == max.
472    if (_max_heap_byte_size == _min_heap_byte_size) {
473      _min_young_size = _max_young_size;
474    }
475  } else {
476    if (FLAG_IS_CMDLINE(NewSize)) {
477      // If NewSize is set on the command line, we should use it as
478      // the initial size, but make sure it is within the heap bounds.
479      _initial_young_size =
480        MIN2(_max_young_size, bound_minus_alignment(NewSize, _initial_heap_byte_size));
481      _min_young_size = bound_minus_alignment(_initial_young_size, _min_heap_byte_size);
482    } else {
483      // For the case where NewSize is not set on the command line, use
484      // NewRatio to size the initial generation size. Use the current
485      // NewSize as the floor, because if NewRatio is overly large, the resulting
486      // size can be too small.
487      _initial_young_size =
488        MIN2(_max_young_size, MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize));
489    }
490  }
491
492  log_trace(gc, heap)("1: Minimum young " SIZE_FORMAT "  Initial young " SIZE_FORMAT "  Maximum young " SIZE_FORMAT,
493                      _min_young_size, _initial_young_size, _max_young_size);
494
495  // At this point the minimum, initial and maximum sizes
496  // of the overall heap and of the young generation have been determined.
497  // The maximum old size can be determined from the maximum young
498  // and maximum heap size since no explicit flags exist
499  // for setting the old generation maximum.
500  _max_old_size = MAX2(_max_heap_byte_size - _max_young_size, _gen_alignment);
501
502  // If no explicit command line flag has been set for the
503  // old generation size, use what is left.
504  if (!FLAG_IS_CMDLINE(OldSize)) {
505    // The user has not specified any value but the ergonomics
506    // may have chosen a value (which may or may not be consistent
507    // with the overall heap size).  In either case make
508    // the minimum, maximum and initial sizes consistent
509    // with the young sizes and the overall heap sizes.
510    _min_old_size = _gen_alignment;
511    _initial_old_size = MIN2(_max_old_size, MAX2(_initial_heap_byte_size - _initial_young_size, _min_old_size));
512    // _max_old_size has already been made consistent above.
513  } else {
514    // OldSize has been explicitly set on the command line. Use it
515    // for the initial size but make sure the minimum allow a young
516    // generation to fit as well.
517    // If the user has explicitly set an OldSize that is inconsistent
518    // with other command line flags, issue a warning.
519    // The generation minimums and the overall heap minimum should
520    // be within one generation alignment.
521    if (_initial_old_size > _max_old_size) {
522      log_warning(gc, ergo)("Inconsistency between maximum heap size and maximum "
523                            "generation sizes: using maximum heap = " SIZE_FORMAT
524                            ", -XX:OldSize flag is being ignored",
525                            _max_heap_byte_size);
526      _initial_old_size = _max_old_size;
527    }
528
529    _min_old_size = MIN2(_initial_old_size, _min_heap_byte_size - _min_young_size);
530  }
531
532  // The initial generation sizes should match the initial heap size,
533  // if not issue a warning and resize the generations. This behavior
534  // differs from JDK8 where the generation sizes have higher priority
535  // than the initial heap size.
536  if ((_initial_old_size + _initial_young_size) != _initial_heap_byte_size) {
537    log_warning(gc, ergo)("Inconsistency between generation sizes and heap size, resizing "
538                          "the generations to fit the heap.");
539
540    size_t desired_young_size = _initial_heap_byte_size - _initial_old_size;
541    if (_initial_heap_byte_size < _initial_old_size) {
542      // Old want all memory, use minimum for young and rest for old
543      _initial_young_size = _min_young_size;
544      _initial_old_size = _initial_heap_byte_size - _min_young_size;
545    } else if (desired_young_size > _max_young_size) {
546      // Need to increase both young and old generation
547      _initial_young_size = _max_young_size;
548      _initial_old_size = _initial_heap_byte_size - _max_young_size;
549    } else if (desired_young_size < _min_young_size) {
550      // Need to decrease both young and old generation
551      _initial_young_size = _min_young_size;
552      _initial_old_size = _initial_heap_byte_size - _min_young_size;
553    } else {
554      // The young generation boundaries allow us to only update the
555      // young generation.
556      _initial_young_size = desired_young_size;
557    }
558
559    log_trace(gc, heap)("2: Minimum young " SIZE_FORMAT "  Initial young " SIZE_FORMAT "  Maximum young " SIZE_FORMAT,
560                    _min_young_size, _initial_young_size, _max_young_size);
561  }
562
563  // Write back to flags if necessary.
564  if (NewSize != _initial_young_size) {
565    FLAG_SET_ERGO(size_t, NewSize, _initial_young_size);
566  }
567
568  if (MaxNewSize != _max_young_size) {
569    FLAG_SET_ERGO(size_t, MaxNewSize, _max_young_size);
570  }
571
572  if (OldSize != _initial_old_size) {
573    FLAG_SET_ERGO(size_t, OldSize, _initial_old_size);
574  }
575
576  log_trace(gc, heap)("Minimum old " SIZE_FORMAT "  Initial old " SIZE_FORMAT "  Maximum old " SIZE_FORMAT,
577                  _min_old_size, _initial_old_size, _max_old_size);
578
579  DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
580}
581
582HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
583                                        bool is_tlab,
584                                        bool* gc_overhead_limit_was_exceeded) {
585  GenCollectedHeap *gch = GenCollectedHeap::heap();
586
587  debug_only(gch->check_for_valid_allocation_state());
588  assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
589
590  // In general gc_overhead_limit_was_exceeded should be false so
591  // set it so here and reset it to true only if the gc time
592  // limit is being exceeded as checked below.
593  *gc_overhead_limit_was_exceeded = false;
594
595  HeapWord* result = NULL;
596
597  // Loop until the allocation is satisfied, or unsatisfied after GC.
598  for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
599    HandleMark hm; // Discard any handles allocated in each iteration.
600
601    // First allocation attempt is lock-free.
602    Generation *young = gch->young_gen();
603    assert(young->supports_inline_contig_alloc(),
604      "Otherwise, must do alloc within heap lock");
605    if (young->should_allocate(size, is_tlab)) {
606      result = young->par_allocate(size, is_tlab);
607      if (result != NULL) {
608        assert(gch->is_in_reserved(result), "result not in heap");
609        return result;
610      }
611    }
612    uint gc_count_before;  // Read inside the Heap_lock locked region.
613    {
614      MutexLocker ml(Heap_lock);
615      log_trace(gc, alloc)("GenCollectorPolicy::mem_allocate_work: attempting locked slow path allocation");
616      // Note that only large objects get a shot at being
617      // allocated in later generations.
618      bool first_only = ! should_try_older_generation_allocation(size);
619
620      result = gch->attempt_allocation(size, is_tlab, first_only);
621      if (result != NULL) {
622        assert(gch->is_in_reserved(result), "result not in heap");
623        return result;
624      }
625
626      if (GCLocker::is_active_and_needs_gc()) {
627        if (is_tlab) {
628          return NULL;  // Caller will retry allocating individual object.
629        }
630        if (!gch->is_maximal_no_gc()) {
631          // Try and expand heap to satisfy request.
632          result = expand_heap_and_allocate(size, is_tlab);
633          // Result could be null if we are out of space.
634          if (result != NULL) {
635            return result;
636          }
637        }
638
639        if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
640          return NULL; // We didn't get to do a GC and we didn't get any memory.
641        }
642
643        // If this thread is not in a jni critical section, we stall
644        // the requestor until the critical section has cleared and
645        // GC allowed. When the critical section clears, a GC is
646        // initiated by the last thread exiting the critical section; so
647        // we retry the allocation sequence from the beginning of the loop,
648        // rather than causing more, now probably unnecessary, GC attempts.
649        JavaThread* jthr = JavaThread::current();
650        if (!jthr->in_critical()) {
651          MutexUnlocker mul(Heap_lock);
652          // Wait for JNI critical section to be exited
653          GCLocker::stall_until_clear();
654          gclocker_stalled_count += 1;
655          continue;
656        } else {
657          if (CheckJNICalls) {
658            fatal("Possible deadlock due to allocating while"
659                  " in jni critical section");
660          }
661          return NULL;
662        }
663      }
664
665      // Read the gc count while the heap lock is held.
666      gc_count_before = gch->total_collections();
667    }
668
669    VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
670    VMThread::execute(&op);
671    if (op.prologue_succeeded()) {
672      result = op.result();
673      if (op.gc_locked()) {
674         assert(result == NULL, "must be NULL if gc_locked() is true");
675         continue;  // Retry and/or stall as necessary.
676      }
677
678      // Allocation has failed and a collection
679      // has been done.  If the gc time limit was exceeded the
680      // this time, return NULL so that an out-of-memory
681      // will be thrown.  Clear gc_overhead_limit_exceeded
682      // so that the overhead exceeded does not persist.
683
684      const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
685      const bool softrefs_clear = all_soft_refs_clear();
686
687      if (limit_exceeded && softrefs_clear) {
688        *gc_overhead_limit_was_exceeded = true;
689        size_policy()->set_gc_overhead_limit_exceeded(false);
690        if (op.result() != NULL) {
691          CollectedHeap::fill_with_object(op.result(), size);
692        }
693        return NULL;
694      }
695      assert(result == NULL || gch->is_in_reserved(result),
696             "result not in heap");
697      return result;
698    }
699
700    // Give a warning if we seem to be looping forever.
701    if ((QueuedAllocationWarningCount > 0) &&
702        (try_count % QueuedAllocationWarningCount == 0)) {
703          log_warning(gc, ergo)("GenCollectorPolicy::mem_allocate_work retries %d times,"
704                                " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
705    }
706  }
707}
708
709HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size,
710                                                       bool   is_tlab) {
711  GenCollectedHeap *gch = GenCollectedHeap::heap();
712  HeapWord* result = NULL;
713  Generation *old = gch->old_gen();
714  if (old->should_allocate(size, is_tlab)) {
715    result = old->expand_and_allocate(size, is_tlab);
716  }
717  if (result == NULL) {
718    Generation *young = gch->young_gen();
719    if (young->should_allocate(size, is_tlab)) {
720      result = young->expand_and_allocate(size, is_tlab);
721    }
722  }
723  assert(result == NULL || gch->is_in_reserved(result), "result not in heap");
724  return result;
725}
726
727HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
728                                                        bool   is_tlab) {
729  GenCollectedHeap *gch = GenCollectedHeap::heap();
730  GCCauseSetter x(gch, GCCause::_allocation_failure);
731  HeapWord* result = NULL;
732
733  assert(size != 0, "Precondition violated");
734  if (GCLocker::is_active_and_needs_gc()) {
735    // GC locker is active; instead of a collection we will attempt
736    // to expand the heap, if there's room for expansion.
737    if (!gch->is_maximal_no_gc()) {
738      result = expand_heap_and_allocate(size, is_tlab);
739    }
740    return result;   // Could be null if we are out of space.
741  } else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) {
742    // Do an incremental collection.
743    gch->do_collection(false,                     // full
744                       false,                     // clear_all_soft_refs
745                       size,                      // size
746                       is_tlab,                   // is_tlab
747                       GenCollectedHeap::OldGen); // max_generation
748  } else {
749    log_trace(gc)(" :: Trying full because partial may fail :: ");
750    // Try a full collection; see delta for bug id 6266275
751    // for the original code and why this has been simplified
752    // with from-space allocation criteria modified and
753    // such allocation moved out of the safepoint path.
754    gch->do_collection(true,                      // full
755                       false,                     // clear_all_soft_refs
756                       size,                      // size
757                       is_tlab,                   // is_tlab
758                       GenCollectedHeap::OldGen); // max_generation
759  }
760
761  result = gch->attempt_allocation(size, is_tlab, false /*first_only*/);
762
763  if (result != NULL) {
764    assert(gch->is_in_reserved(result), "result not in heap");
765    return result;
766  }
767
768  // OK, collection failed, try expansion.
769  result = expand_heap_and_allocate(size, is_tlab);
770  if (result != NULL) {
771    return result;
772  }
773
774  // If we reach this point, we're really out of memory. Try every trick
775  // we can to reclaim memory. Force collection of soft references. Force
776  // a complete compaction of the heap. Any additional methods for finding
777  // free memory should be here, especially if they are expensive. If this
778  // attempt fails, an OOM exception will be thrown.
779  {
780    UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
781
782    gch->do_collection(true,                      // full
783                       true,                      // clear_all_soft_refs
784                       size,                      // size
785                       is_tlab,                   // is_tlab
786                       GenCollectedHeap::OldGen); // max_generation
787  }
788
789  result = gch->attempt_allocation(size, is_tlab, false /* first_only */);
790  if (result != NULL) {
791    assert(gch->is_in_reserved(result), "result not in heap");
792    return result;
793  }
794
795  assert(!should_clear_all_soft_refs(),
796    "Flag should have been handled and cleared prior to this point");
797
798  // What else?  We might try synchronous finalization later.  If the total
799  // space available is large enough for the allocation, then a more
800  // complete compaction phase than we've tried so far might be
801  // appropriate.
802  return NULL;
803}
804
805MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
806                                                 ClassLoaderData* loader_data,
807                                                 size_t word_size,
808                                                 Metaspace::MetadataType mdtype) {
809  uint loop_count = 0;
810  uint gc_count = 0;
811  uint full_gc_count = 0;
812
813  assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
814
815  do {
816    MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
817    if (result != NULL) {
818      return result;
819    }
820
821    if (GCLocker::is_active_and_needs_gc()) {
822      // If the GCLocker is active, just expand and allocate.
823      // If that does not succeed, wait if this thread is not
824      // in a critical section itself.
825      result =
826        loader_data->metaspace_non_null()->expand_and_allocate(word_size,
827                                                               mdtype);
828      if (result != NULL) {
829        return result;
830      }
831      JavaThread* jthr = JavaThread::current();
832      if (!jthr->in_critical()) {
833        // Wait for JNI critical section to be exited
834        GCLocker::stall_until_clear();
835        // The GC invoked by the last thread leaving the critical
836        // section will be a young collection and a full collection
837        // is (currently) needed for unloading classes so continue
838        // to the next iteration to get a full GC.
839        continue;
840      } else {
841        if (CheckJNICalls) {
842          fatal("Possible deadlock due to allocating while"
843                " in jni critical section");
844        }
845        return NULL;
846      }
847    }
848
849    {  // Need lock to get self consistent gc_count's
850      MutexLocker ml(Heap_lock);
851      gc_count      = Universe::heap()->total_collections();
852      full_gc_count = Universe::heap()->total_full_collections();
853    }
854
855    // Generate a VM operation
856    VM_CollectForMetadataAllocation op(loader_data,
857                                       word_size,
858                                       mdtype,
859                                       gc_count,
860                                       full_gc_count,
861                                       GCCause::_metadata_GC_threshold);
862    VMThread::execute(&op);
863
864    // If GC was locked out, try again. Check before checking success because the
865    // prologue could have succeeded and the GC still have been locked out.
866    if (op.gc_locked()) {
867      continue;
868    }
869
870    if (op.prologue_succeeded()) {
871      return op.result();
872    }
873    loop_count++;
874    if ((QueuedAllocationWarningCount > 0) &&
875        (loop_count % QueuedAllocationWarningCount == 0)) {
876      log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
877                            " size=" SIZE_FORMAT, loop_count, word_size);
878    }
879  } while (true);  // Until a GC is done
880}
881
882// Return true if any of the following is true:
883// . the allocation won't fit into the current young gen heap
884// . gc locker is occupied (jni critical section)
885// . heap memory is tight -- the most recent previous collection
886//   was a full collection because a partial collection (would
887//   have) failed and is likely to fail again
888bool GenCollectorPolicy::should_try_older_generation_allocation(
889        size_t word_size) const {
890  GenCollectedHeap* gch = GenCollectedHeap::heap();
891  size_t young_capacity = gch->young_gen()->capacity_before_gc();
892  return    (word_size > heap_word_size(young_capacity))
893         || GCLocker::is_active_and_needs_gc()
894         || gch->incremental_collection_failed();
895}
896
897
898//
899// MarkSweepPolicy methods
900//
901
902void MarkSweepPolicy::initialize_alignments() {
903  _space_alignment = _gen_alignment = (size_t)Generation::GenGrain;
904  _heap_alignment = compute_heap_alignment();
905}
906
907void MarkSweepPolicy::initialize_generations() {
908  _young_gen_spec = new GenerationSpec(Generation::DefNew, _initial_young_size, _max_young_size, _gen_alignment);
909  _old_gen_spec   = new GenerationSpec(Generation::MarkSweepCompact, _initial_old_size, _max_old_size, _gen_alignment);
910}
911
912void MarkSweepPolicy::initialize_gc_policy_counters() {
913  // Initialize the policy counters - 2 collectors, 3 generations.
914  _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
915}
916
917/////////////// Unit tests ///////////////
918
919#ifndef PRODUCT
920// Testing that the NewSize flag is handled correct is hard because it
921// depends on so many other configurable variables. This test only tries to
922// verify that there are some basic rules for NewSize honored by the policies.
923class TestGenCollectorPolicy {
924public:
925  static void test_new_size() {
926    size_t flag_value;
927
928    save_flags();
929
930    // If NewSize has been ergonomically set, the collector policy
931    // should use it for min but calculate the initial young size
932    // using NewRatio.
933    flag_value = 20 * M;
934    set_basic_flag_values();
935    FLAG_SET_ERGO(size_t, NewSize, flag_value);
936    verify_young_min(flag_value);
937
938    set_basic_flag_values();
939    FLAG_SET_ERGO(size_t, NewSize, flag_value);
940    verify_scaled_young_initial(InitialHeapSize);
941
942    // If NewSize is set on the command line, it should be used
943    // for both min and initial young size if less than min heap.
944    // Note that once a flag has been set with FLAG_SET_CMDLINE it
945    // will be treated as it have been set on the command line for
946    // the rest of the VM lifetime. This is an irreversible change.
947    flag_value = 20 * M;
948    set_basic_flag_values();
949    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
950    verify_young_min(flag_value);
951
952    set_basic_flag_values();
953    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
954    verify_young_initial(flag_value);
955
956    // If NewSize is set on command line, but is larger than the min
957    // heap size, it should only be used for initial young size.
958    flag_value = 80 * M;
959    set_basic_flag_values();
960    FLAG_SET_CMDLINE(size_t, NewSize, flag_value);
961    verify_young_initial(flag_value);
962
963    restore_flags();
964  }
965
966  static void test_old_size() {
967    size_t flag_value;
968    size_t heap_alignment = CollectorPolicy::compute_heap_alignment();
969
970    save_flags();
971
972    // If OldSize is set on the command line, it should be used
973    // for both min and initial old size if less than min heap.
974    flag_value = 20 * M;
975    set_basic_flag_values();
976    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
977    verify_old_min(flag_value);
978
979    set_basic_flag_values();
980    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
981    // Calculate what we expect the flag to be.
982    size_t expected_old_initial = align_size_up(InitialHeapSize, heap_alignment) - MaxNewSize;
983    verify_old_initial(expected_old_initial);
984
985    // If MaxNewSize is large, the maximum OldSize will be less than
986    // what's requested on the command line and it should be reset
987    // ergonomically.
988    // We intentionally set MaxNewSize + OldSize > MaxHeapSize (see over_size).
989    flag_value = 30 * M;
990    set_basic_flag_values();
991    FLAG_SET_CMDLINE(size_t, OldSize, flag_value);
992    size_t over_size = 20*M;
993    size_t new_size_value = align_size_up(MaxHeapSize, heap_alignment) - flag_value + over_size;
994    FLAG_SET_CMDLINE(size_t, MaxNewSize, new_size_value);
995    // Calculate what we expect the flag to be.
996    expected_old_initial = align_size_up(MaxHeapSize, heap_alignment) - MaxNewSize;
997    verify_old_initial(expected_old_initial);
998    restore_flags();
999  }
1000
1001  static void verify_young_min(size_t expected) {
1002    MarkSweepPolicy msp;
1003    msp.initialize_all();
1004
1005    assert(msp.min_young_size() <= expected, "%zu  > %zu", msp.min_young_size(), expected);
1006  }
1007
1008  static void verify_young_initial(size_t expected) {
1009    MarkSweepPolicy msp;
1010    msp.initialize_all();
1011
1012    assert(msp.initial_young_size() == expected, "%zu != %zu", msp.initial_young_size(), expected);
1013  }
1014
1015  static void verify_scaled_young_initial(size_t initial_heap_size) {
1016    MarkSweepPolicy msp;
1017    msp.initialize_all();
1018
1019    if (InitialHeapSize > initial_heap_size) {
1020      // InitialHeapSize was adapted by msp.initialize_all, e.g. due to alignment
1021      // caused by 64K page size.
1022      initial_heap_size = InitialHeapSize;
1023    }
1024
1025    size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size);
1026    assert(msp.initial_young_size() == expected, "%zu != %zu", msp.initial_young_size(), expected);
1027    assert(FLAG_IS_ERGO(NewSize) && NewSize == expected,
1028        "NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize);
1029  }
1030
1031  static void verify_old_min(size_t expected) {
1032    MarkSweepPolicy msp;
1033    msp.initialize_all();
1034
1035    assert(msp.min_old_size() <= expected, "%zu  > %zu", msp.min_old_size(), expected);
1036  }
1037
1038  static void verify_old_initial(size_t expected) {
1039    MarkSweepPolicy msp;
1040    msp.initialize_all();
1041
1042    assert(msp.initial_old_size() == expected, "%zu != %zu", msp.initial_old_size(), expected);
1043  }
1044
1045
1046private:
1047  static size_t original_InitialHeapSize;
1048  static size_t original_MaxHeapSize;
1049  static size_t original_MaxNewSize;
1050  static size_t original_MinHeapDeltaBytes;
1051  static size_t original_NewSize;
1052  static size_t original_OldSize;
1053
1054  static void set_basic_flag_values() {
1055    FLAG_SET_ERGO(size_t, MaxHeapSize, 180 * M);
1056    FLAG_SET_ERGO(size_t, InitialHeapSize, 100 * M);
1057    FLAG_SET_ERGO(size_t, OldSize, 4 * M);
1058    FLAG_SET_ERGO(size_t, NewSize, 1 * M);
1059    FLAG_SET_ERGO(size_t, MaxNewSize, 80 * M);
1060    Arguments::set_min_heap_size(40 * M);
1061  }
1062
1063  static void save_flags() {
1064    original_InitialHeapSize   = InitialHeapSize;
1065    original_MaxHeapSize       = MaxHeapSize;
1066    original_MaxNewSize        = MaxNewSize;
1067    original_MinHeapDeltaBytes = MinHeapDeltaBytes;
1068    original_NewSize           = NewSize;
1069    original_OldSize           = OldSize;
1070  }
1071
1072  static void restore_flags() {
1073    InitialHeapSize   = original_InitialHeapSize;
1074    MaxHeapSize       = original_MaxHeapSize;
1075    MaxNewSize        = original_MaxNewSize;
1076    MinHeapDeltaBytes = original_MinHeapDeltaBytes;
1077    NewSize           = original_NewSize;
1078    OldSize           = original_OldSize;
1079  }
1080};
1081
1082size_t TestGenCollectorPolicy::original_InitialHeapSize   = 0;
1083size_t TestGenCollectorPolicy::original_MaxHeapSize       = 0;
1084size_t TestGenCollectorPolicy::original_MaxNewSize        = 0;
1085size_t TestGenCollectorPolicy::original_MinHeapDeltaBytes = 0;
1086size_t TestGenCollectorPolicy::original_NewSize           = 0;
1087size_t TestGenCollectorPolicy::original_OldSize           = 0;
1088
1089void TestNewSize_test() {
1090  TestGenCollectorPolicy::test_new_size();
1091}
1092
1093void TestOldSize_test() {
1094  TestGenCollectorPolicy::test_old_size();
1095}
1096
1097#endif
1098