void TwoGenerationCollectorPolicy::initialize_flags() { GenCollectorPolicy::initialize_flags(); if (!is_size_aligned(OldSize, _gen_alignment)) { FLAG_SET_ERGO(uintx, OldSize, align_size_down(OldSize, _gen_alignment)); } if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) { // NewRatio will be used later to set the young generation size so we use // it to calculate how big the heap should be based on the requested OldSize // and NewRatio. assert(NewRatio > 0, "NewRatio should have been set up earlier"); size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1); calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment); FLAG_SET_ERGO(uintx, MaxHeapSize, calculated_heapsize); _max_heap_byte_size = MaxHeapSize; FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize); _initial_heap_byte_size = InitialHeapSize; } // adjust max heap size if necessary if (NewSize + OldSize > MaxHeapSize) { if (_max_heap_size_cmdline) { // somebody set a maximum heap size with the intention that we should not // exceed it. Adjust New/OldSize as necessary. uintx calculated_size = NewSize + OldSize; double shrink_factor = (double) MaxHeapSize / calculated_size; uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment); FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size)); _initial_gen0_size = NewSize; // OldSize is already aligned because above we aligned MaxHeapSize to // _heap_alignment, and we just made sure that NewSize is aligned to // _gen_alignment. In initialize_flags() we verified that _heap_alignment // is a multiple of _gen_alignment. FLAG_SET_ERGO(uintx, OldSize, MaxHeapSize - NewSize); } else { FLAG_SET_ERGO(uintx, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment)); _max_heap_byte_size = MaxHeapSize; } } always_do_update_barrier = UseConcMarkSweepGC; DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_flags();) }
// Call this method during the sizing of the gen1 to make // adjustments to gen0 because of gen1 sizing policy. gen0 initially has // the most freedom in sizing because it is done before the // policy for gen1 is applied. Once gen1 policies have been applied, // there may be conflicts in the shape of the heap and this method // is used to make the needed adjustments. The application of the // policies could be more sophisticated (iterative for example) but // keeping it simple also seems a worthwhile goal. bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr, size_t* gen1_size_ptr, const size_t heap_size) { bool result = false; if ((*gen0_size_ptr + *gen1_size_ptr) > heap_size) { uintx smallest_new_size = young_gen_size_lower_bound(); if ((heap_size < (*gen0_size_ptr + _min_gen1_size)) && (heap_size >= _min_gen1_size + smallest_new_size)) { // Adjust gen0 down to accommodate _min_gen1_size *gen0_size_ptr = align_size_down_bounded(heap_size - _min_gen1_size, _gen_alignment); result = true; } else { *gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _gen_alignment); } } return result; }
void GenCollectorPolicy::initialize_flags() { CollectorPolicy::initialize_flags(); assert(_gen_alignment != 0, "Generation alignment not set up properly"); assert(_heap_alignment >= _gen_alignment, err_msg("heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT, _heap_alignment, _gen_alignment)); assert(_gen_alignment % _space_alignment == 0, err_msg("gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT, _gen_alignment, _space_alignment)); assert(_heap_alignment % _gen_alignment == 0, err_msg("heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT, _heap_alignment, _gen_alignment)); // All generational heaps have a youngest gen; handle those flags here // Make sure the heap is large enough for two generations uintx smallest_new_size = young_gen_size_lower_bound(); uintx smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment), _heap_alignment); if (MaxHeapSize < smallest_heap_size) { FLAG_SET_ERGO(uintx, MaxHeapSize, smallest_heap_size); _max_heap_byte_size = MaxHeapSize; } // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size if (_min_heap_byte_size < smallest_heap_size) { _min_heap_byte_size = smallest_heap_size; if (InitialHeapSize < _min_heap_byte_size) { FLAG_SET_ERGO(uintx, InitialHeapSize, smallest_heap_size); _initial_heap_byte_size = smallest_heap_size; } } // Now take the actual NewSize into account. We will silently increase NewSize // if the user specified a smaller or unaligned value. smallest_new_size = MAX2(smallest_new_size, (uintx)align_size_down(NewSize, _gen_alignment)); if (smallest_new_size != NewSize) { // Do not use FLAG_SET_ERGO to update NewSize here, since this will override // if NewSize was set on the command line or not. This information is needed // later when setting the initial and minimum young generation size. NewSize = smallest_new_size; } _initial_gen0_size = NewSize; if (!FLAG_IS_DEFAULT(MaxNewSize)) { uintx min_new_size = MAX2(_gen_alignment, _min_gen0_size); if (MaxNewSize >= MaxHeapSize) { // Make sure there is room for an old generation uintx smaller_max_new_size = MaxHeapSize - _gen_alignment; if (FLAG_IS_CMDLINE(MaxNewSize)) { warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire " "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.", MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K); } FLAG_SET_ERGO(uintx, MaxNewSize, smaller_max_new_size); if (NewSize > MaxNewSize) { FLAG_SET_ERGO(uintx, NewSize, MaxNewSize); _initial_gen0_size = NewSize; } } else if (MaxNewSize < min_new_size) { FLAG_SET_ERGO(uintx, MaxNewSize, min_new_size); } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) { FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment)); } _max_gen0_size = MaxNewSize; } if (NewSize > MaxNewSize) { // At this point this should only happen if the user specifies a large NewSize and/or // a small (but not too small) MaxNewSize. if (FLAG_IS_CMDLINE(MaxNewSize)) { warning("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). " "A new max generation size of " SIZE_FORMAT "k will be used.", NewSize/K, MaxNewSize/K, NewSize/K); } FLAG_SET_ERGO(uintx, MaxNewSize, NewSize); _max_gen0_size = MaxNewSize; } if (SurvivorRatio < 1 || NewRatio < 1) { vm_exit_during_initialization("Invalid young gen ratio specified"); } DEBUG_ONLY(GenCollectorPolicy::assert_flags();) }
void GenCollectorPolicy::initialize_flags() { CollectorPolicy::initialize_flags(); assert(_gen_alignment != 0, "Generation alignment not set up properly"); assert(_heap_alignment >= _gen_alignment, "heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT, _heap_alignment, _gen_alignment); assert(_gen_alignment % _space_alignment == 0, "gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT, _gen_alignment, _space_alignment); assert(_heap_alignment % _gen_alignment == 0, "heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT, _heap_alignment, _gen_alignment); // All generational heaps have a young gen; handle those flags here // Make sure the heap is large enough for two generations size_t smallest_new_size = young_gen_size_lower_bound(); size_t smallest_heap_size = align_size_up(smallest_new_size + old_gen_size_lower_bound(), _heap_alignment); if (MaxHeapSize < smallest_heap_size) { FLAG_SET_ERGO(size_t, MaxHeapSize, smallest_heap_size); _max_heap_byte_size = MaxHeapSize; } // If needed, synchronize _min_heap_byte size and _initial_heap_byte_size if (_min_heap_byte_size < smallest_heap_size) { _min_heap_byte_size = smallest_heap_size; if (InitialHeapSize < _min_heap_byte_size) { FLAG_SET_ERGO(size_t, InitialHeapSize, smallest_heap_size); _initial_heap_byte_size = smallest_heap_size; } } // Make sure NewSize allows an old generation to fit even if set on the command line if (FLAG_IS_CMDLINE(NewSize) && NewSize >= _initial_heap_byte_size) { log_warning(gc, ergo)("NewSize was set larger than initial heap size, will use initial heap size."); FLAG_SET_ERGO(size_t, NewSize, bound_minus_alignment(NewSize, _initial_heap_byte_size)); } // Now take the actual NewSize into account. We will silently increase NewSize // if the user specified a smaller or unaligned value. size_t bounded_new_size = bound_minus_alignment(NewSize, MaxHeapSize); bounded_new_size = MAX2(smallest_new_size, (size_t)align_size_down(bounded_new_size, _gen_alignment)); if (bounded_new_size != NewSize) { FLAG_SET_ERGO(size_t, NewSize, bounded_new_size); } _min_young_size = smallest_new_size; _initial_young_size = NewSize; if (!FLAG_IS_DEFAULT(MaxNewSize)) { if (MaxNewSize >= MaxHeapSize) { // Make sure there is room for an old generation size_t smaller_max_new_size = MaxHeapSize - _gen_alignment; if (FLAG_IS_CMDLINE(MaxNewSize)) { log_warning(gc, ergo)("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire " "heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.", MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K); } FLAG_SET_ERGO(size_t, MaxNewSize, smaller_max_new_size); if (NewSize > MaxNewSize) { FLAG_SET_ERGO(size_t, NewSize, MaxNewSize); _initial_young_size = NewSize; } } else if (MaxNewSize < _initial_young_size) { FLAG_SET_ERGO(size_t, MaxNewSize, _initial_young_size); } else if (!is_size_aligned(MaxNewSize, _gen_alignment)) { FLAG_SET_ERGO(size_t, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment)); } _max_young_size = MaxNewSize; } if (NewSize > MaxNewSize) { // At this point this should only happen if the user specifies a large NewSize and/or // a small (but not too small) MaxNewSize. if (FLAG_IS_CMDLINE(MaxNewSize)) { log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). " "A new max generation size of " SIZE_FORMAT "k will be used.", NewSize/K, MaxNewSize/K, NewSize/K); } FLAG_SET_ERGO(size_t, MaxNewSize, NewSize); _max_young_size = MaxNewSize; } if (SurvivorRatio < 1 || NewRatio < 1) { vm_exit_during_initialization("Invalid young gen ratio specified"); } if (OldSize < old_gen_size_lower_bound()) { FLAG_SET_ERGO(size_t, OldSize, old_gen_size_lower_bound()); } if (!is_size_aligned(OldSize, _gen_alignment)) { FLAG_SET_ERGO(size_t, OldSize, align_size_down(OldSize, _gen_alignment)); } if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) { // NewRatio will be used later to set the young generation size so we use // it to calculate how big the heap should be based on the requested OldSize // and NewRatio. assert(NewRatio > 0, "NewRatio should have been set up earlier"); size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1); calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment); FLAG_SET_ERGO(size_t, MaxHeapSize, calculated_heapsize); _max_heap_byte_size = MaxHeapSize; FLAG_SET_ERGO(size_t, InitialHeapSize, calculated_heapsize); _initial_heap_byte_size = InitialHeapSize; } // Adjust NewSize and OldSize or MaxHeapSize to match each other if (NewSize + OldSize > MaxHeapSize) { if (FLAG_IS_CMDLINE(MaxHeapSize)) { // Somebody has set a maximum heap size with the intention that we should not // exceed it. Adjust New/OldSize as necessary. size_t calculated_size = NewSize + OldSize; double shrink_factor = (double) MaxHeapSize / calculated_size; size_t smaller_new_size = align_size_down((size_t)(NewSize * shrink_factor), _gen_alignment); FLAG_SET_ERGO(size_t, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size)); _initial_young_size = NewSize; // OldSize is already aligned because above we aligned MaxHeapSize to // _heap_alignment, and we just made sure that NewSize is aligned to // _gen_alignment. In initialize_flags() we verified that _heap_alignment // is a multiple of _gen_alignment. FLAG_SET_ERGO(size_t, OldSize, MaxHeapSize - NewSize); } else { FLAG_SET_ERGO(size_t, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment)); _max_heap_byte_size = MaxHeapSize; } } // Update NewSize, if possible, to avoid sizing the young gen too small when only // OldSize is set on the command line. if (FLAG_IS_CMDLINE(OldSize) && !FLAG_IS_CMDLINE(NewSize)) { if (OldSize < _initial_heap_byte_size) { size_t new_size = _initial_heap_byte_size - OldSize; // Need to compare against the flag value for max since _max_young_size // might not have been set yet. if (new_size >= _min_young_size && new_size <= MaxNewSize) { FLAG_SET_ERGO(size_t, NewSize, new_size); _initial_young_size = NewSize; } } } always_do_update_barrier = UseConcMarkSweepGC; DEBUG_ONLY(GenCollectorPolicy::assert_flags();) }