Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/memory/collectorPolicy.cpp
32285 views
/*1* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "gc_implementation/shared/adaptiveSizePolicy.hpp"26#include "gc_implementation/shared/gcPolicyCounters.hpp"27#include "gc_implementation/shared/vmGCOperations.hpp"28#include "memory/cardTableRS.hpp"29#include "memory/collectorPolicy.hpp"30#include "memory/gcLocker.inline.hpp"31#include "memory/genCollectedHeap.hpp"32#include "memory/generationSpec.hpp"33#include "memory/space.hpp"34#include "memory/universe.hpp"35#include "runtime/arguments.hpp"36#include "runtime/globals_extension.hpp"37#include "runtime/handles.inline.hpp"38#include "runtime/java.hpp"39#include "runtime/thread.inline.hpp"40#include "runtime/vmThread.hpp"41#include "utilities/macros.hpp"42#if INCLUDE_ALL_GCS43#include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"44#include "gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp"45#endif // INCLUDE_ALL_GCS4647// CollectorPolicy methods.4849CollectorPolicy::CollectorPolicy() :50_space_alignment(0),51_heap_alignment(0),52_initial_heap_byte_size(InitialHeapSize),53_max_heap_byte_size(MaxHeapSize),54_min_heap_byte_size(Arguments::min_heap_size()),55_max_heap_size_cmdline(false),56_size_policy(NULL),57_should_clear_all_soft_refs(false),58_all_soft_refs_clear(false)59{}6061#ifdef ASSERT62void CollectorPolicy::assert_flags() {63assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes");64assert(InitialHeapSize % _heap_alignment == 0, "InitialHeapSize alignment");65assert(MaxHeapSize % _heap_alignment == 0, "MaxHeapSize alignment");66}6768void CollectorPolicy::assert_size_info() {69assert(InitialHeapSize == _initial_heap_byte_size, "Discrepancy between InitialHeapSize flag and local storage");70assert(MaxHeapSize == _max_heap_byte_size, "Discrepancy between MaxHeapSize flag and local storage");71assert(_max_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible minimum and maximum heap sizes");72assert(_initial_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible initial and minimum heap sizes");73assert(_max_heap_byte_size >= _initial_heap_byte_size, "Ergonomics decided on incompatible initial and maximum heap sizes");74assert(_min_heap_byte_size % _heap_alignment == 0, "min_heap_byte_size alignment");75assert(_initial_heap_byte_size % _heap_alignment == 0, "initial_heap_byte_size alignment");76assert(_max_heap_byte_size % _heap_alignment == 0, "max_heap_byte_size alignment");77}78#endif // ASSERT7980void CollectorPolicy::initialize_flags() {81assert(_space_alignment != 0, "Space alignment not set up properly");82assert(_heap_alignment != 0, "Heap alignment not set up properly");83assert(_heap_alignment >= _space_alignment,84err_msg("heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,85_heap_alignment, _space_alignment));86assert(_heap_alignment % _space_alignment == 0,87err_msg("heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,88_heap_alignment, _space_alignment));8990if (FLAG_IS_CMDLINE(MaxHeapSize)) {91if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {92vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size");93}94if (_min_heap_byte_size != 0 && MaxHeapSize < _min_heap_byte_size) {95vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");96}97_max_heap_size_cmdline = true;98}99100// Check heap parameter properties101if (InitialHeapSize < M) {102vm_exit_during_initialization("Too small initial heap");103}104if (_min_heap_byte_size < M) {105vm_exit_during_initialization("Too small minimum heap");106}107108// User inputs from -Xmx and -Xms must be aligned109_min_heap_byte_size = align_size_up(_min_heap_byte_size, _heap_alignment);110uintx aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);111uintx aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);112113// Write back to flags if the values changed114if (aligned_initial_heap_size != InitialHeapSize) {115FLAG_SET_ERGO(uintx, InitialHeapSize, aligned_initial_heap_size);116}117if (aligned_max_heap_size != MaxHeapSize) {118FLAG_SET_ERGO(uintx, MaxHeapSize, aligned_max_heap_size);119}120121if (FLAG_IS_CMDLINE(InitialHeapSize) && _min_heap_byte_size != 0 &&122InitialHeapSize < _min_heap_byte_size) {123vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");124}125if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {126FLAG_SET_ERGO(uintx, MaxHeapSize, InitialHeapSize);127} else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {128FLAG_SET_ERGO(uintx, InitialHeapSize, MaxHeapSize);129if (InitialHeapSize < _min_heap_byte_size) {130_min_heap_byte_size = InitialHeapSize;131}132}133134_initial_heap_byte_size = InitialHeapSize;135_max_heap_byte_size = MaxHeapSize;136137FLAG_SET_ERGO(uintx, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));138139DEBUG_ONLY(CollectorPolicy::assert_flags();)140}141142void CollectorPolicy::initialize_size_info() {143if (PrintGCDetails && Verbose) {144gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "145SIZE_FORMAT " Maximum heap " SIZE_FORMAT,146_min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);147}148149DEBUG_ONLY(CollectorPolicy::assert_size_info();)150}151152bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {153bool result = _should_clear_all_soft_refs;154set_should_clear_all_soft_refs(false);155return result;156}157158GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap,159int max_covered_regions) {160return new CardTableRS(whole_heap, max_covered_regions);161}162163void CollectorPolicy::cleared_all_soft_refs() {164// If near gc overhear limit, continue to clear SoftRefs. SoftRefs may165// have been cleared in the last collection but if the gc overhear166// limit continues to be near, SoftRefs should still be cleared.167if (size_policy() != NULL) {168_should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near();169}170_all_soft_refs_clear = true;171}172173size_t CollectorPolicy::compute_heap_alignment() {174// The card marking array and the offset arrays for old generations are175// committed in os pages as well. Make sure they are entirely full (to176// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1177// byte entry and the os page size is 4096, the maximum heap size should178// be 512*4096 = 2MB aligned.179180// There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable181// is supported.182// Requirements of any new remembered set implementations must be added here.183size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);184185if (UseLargePages) {186// In presence of large pages we have to make sure that our187// alignment is large page aware.188alignment = lcm(os::large_page_size(), alignment);189}190191return alignment;192}193194// GenCollectorPolicy methods.195196GenCollectorPolicy::GenCollectorPolicy() :197_min_gen0_size(0),198_initial_gen0_size(0),199_max_gen0_size(0),200_gen_alignment(0),201_generations(NULL)202{}203204size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {205return align_size_down_bounded(base_size / (NewRatio + 1), _gen_alignment);206}207208size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,209size_t maximum_size) {210size_t max_minus = maximum_size - _gen_alignment;211return desired_size < max_minus ? desired_size : max_minus;212}213214215void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,216size_t init_promo_size,217size_t init_survivor_size) {218const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;219_size_policy = new AdaptiveSizePolicy(init_eden_size,220init_promo_size,221init_survivor_size,222max_gc_pause_sec,223GCTimeRatio);224}225226size_t GenCollectorPolicy::young_gen_size_lower_bound() {227// The young generation must be aligned and have room for eden + two survivors228return align_size_up(3 * _space_alignment, _gen_alignment);229}230231#ifdef ASSERT232void GenCollectorPolicy::assert_flags() {233CollectorPolicy::assert_flags();234assert(NewSize >= _min_gen0_size, "Ergonomics decided on a too small young gen size");235assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes");236assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes");237assert(NewSize % _gen_alignment == 0, "NewSize alignment");238assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % _gen_alignment == 0, "MaxNewSize alignment");239}240241void TwoGenerationCollectorPolicy::assert_flags() {242GenCollectorPolicy::assert_flags();243assert(OldSize + NewSize <= MaxHeapSize, "Ergonomics decided on incompatible generation and heap sizes");244assert(OldSize % _gen_alignment == 0, "OldSize alignment");245}246247void GenCollectorPolicy::assert_size_info() {248CollectorPolicy::assert_size_info();249// GenCollectorPolicy::initialize_size_info may update the MaxNewSize250assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes");251assert(NewSize == _initial_gen0_size, "Discrepancy between NewSize flag and local storage");252assert(MaxNewSize == _max_gen0_size, "Discrepancy between MaxNewSize flag and local storage");253assert(_min_gen0_size <= _initial_gen0_size, "Ergonomics decided on incompatible minimum and initial young gen sizes");254assert(_initial_gen0_size <= _max_gen0_size, "Ergonomics decided on incompatible initial and maximum young gen sizes");255assert(_min_gen0_size % _gen_alignment == 0, "_min_gen0_size alignment");256assert(_initial_gen0_size % _gen_alignment == 0, "_initial_gen0_size alignment");257assert(_max_gen0_size % _gen_alignment == 0, "_max_gen0_size alignment");258}259260void TwoGenerationCollectorPolicy::assert_size_info() {261GenCollectorPolicy::assert_size_info();262assert(OldSize == _initial_gen1_size, "Discrepancy between OldSize flag and local storage");263assert(_min_gen1_size <= _initial_gen1_size, "Ergonomics decided on incompatible minimum and initial old gen sizes");264assert(_initial_gen1_size <= _max_gen1_size, "Ergonomics decided on incompatible initial and maximum old gen sizes");265assert(_max_gen1_size % _gen_alignment == 0, "_max_gen1_size alignment");266assert(_initial_gen1_size % _gen_alignment == 0, "_initial_gen1_size alignment");267assert(_max_heap_byte_size <= (_max_gen0_size + _max_gen1_size), "Total maximum heap sizes must be sum of generation maximum sizes");268}269#endif // ASSERT270271void GenCollectorPolicy::initialize_flags() {272CollectorPolicy::initialize_flags();273274assert(_gen_alignment != 0, "Generation alignment not set up properly");275assert(_heap_alignment >= _gen_alignment,276err_msg("heap_alignment: " SIZE_FORMAT " less than gen_alignment: " SIZE_FORMAT,277_heap_alignment, _gen_alignment));278assert(_gen_alignment % _space_alignment == 0,279err_msg("gen_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,280_gen_alignment, _space_alignment));281assert(_heap_alignment % _gen_alignment == 0,282err_msg("heap_alignment: " SIZE_FORMAT " not aligned by gen_alignment: " SIZE_FORMAT,283_heap_alignment, _gen_alignment));284285// All generational heaps have a youngest gen; handle those flags here286287// Make sure the heap is large enough for two generations288uintx smallest_new_size = young_gen_size_lower_bound();289uintx smallest_heap_size = align_size_up(smallest_new_size + align_size_up(_space_alignment, _gen_alignment),290_heap_alignment);291if (MaxHeapSize < smallest_heap_size) {292FLAG_SET_ERGO(uintx, MaxHeapSize, smallest_heap_size);293_max_heap_byte_size = MaxHeapSize;294}295// If needed, synchronize _min_heap_byte size and _initial_heap_byte_size296if (_min_heap_byte_size < smallest_heap_size) {297_min_heap_byte_size = smallest_heap_size;298if (InitialHeapSize < _min_heap_byte_size) {299FLAG_SET_ERGO(uintx, InitialHeapSize, smallest_heap_size);300_initial_heap_byte_size = smallest_heap_size;301}302}303304// Now take the actual NewSize into account. We will silently increase NewSize305// if the user specified a smaller or unaligned value.306smallest_new_size = MAX2(smallest_new_size, (uintx)align_size_down(NewSize, _gen_alignment));307if (smallest_new_size != NewSize) {308// Do not use FLAG_SET_ERGO to update NewSize here, since this will override309// if NewSize was set on the command line or not. This information is needed310// later when setting the initial and minimum young generation size.311NewSize = smallest_new_size;312}313_initial_gen0_size = NewSize;314315if (!FLAG_IS_DEFAULT(MaxNewSize)) {316uintx min_new_size = MAX2(_gen_alignment, _min_gen0_size);317318if (MaxNewSize >= MaxHeapSize) {319// Make sure there is room for an old generation320uintx smaller_max_new_size = MaxHeapSize - _gen_alignment;321if (FLAG_IS_CMDLINE(MaxNewSize)) {322warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or greater than the entire "323"heap (" SIZE_FORMAT "k). A new max generation size of " SIZE_FORMAT "k will be used.",324MaxNewSize/K, MaxHeapSize/K, smaller_max_new_size/K);325}326FLAG_SET_ERGO(uintx, MaxNewSize, smaller_max_new_size);327if (NewSize > MaxNewSize) {328FLAG_SET_ERGO(uintx, NewSize, MaxNewSize);329_initial_gen0_size = NewSize;330}331} else if (MaxNewSize < min_new_size) {332FLAG_SET_ERGO(uintx, MaxNewSize, min_new_size);333} else if (!is_size_aligned(MaxNewSize, _gen_alignment)) {334FLAG_SET_ERGO(uintx, MaxNewSize, align_size_down(MaxNewSize, _gen_alignment));335}336_max_gen0_size = MaxNewSize;337}338339if (NewSize > MaxNewSize) {340// At this point this should only happen if the user specifies a large NewSize and/or341// a small (but not too small) MaxNewSize.342if (FLAG_IS_CMDLINE(MaxNewSize)) {343warning("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "344"A new max generation size of " SIZE_FORMAT "k will be used.",345NewSize/K, MaxNewSize/K, NewSize/K);346}347FLAG_SET_ERGO(uintx, MaxNewSize, NewSize);348_max_gen0_size = MaxNewSize;349}350351if (SurvivorRatio < 1 || NewRatio < 1) {352vm_exit_during_initialization("Invalid young gen ratio specified");353}354355DEBUG_ONLY(GenCollectorPolicy::assert_flags();)356}357358void TwoGenerationCollectorPolicy::initialize_flags() {359GenCollectorPolicy::initialize_flags();360361if (!is_size_aligned(OldSize, _gen_alignment)) {362FLAG_SET_ERGO(uintx, OldSize, align_size_down(OldSize, _gen_alignment));363}364365if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {366// NewRatio will be used later to set the young generation size so we use367// it to calculate how big the heap should be based on the requested OldSize368// and NewRatio.369assert(NewRatio > 0, "NewRatio should have been set up earlier");370size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);371372calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment);373FLAG_SET_ERGO(uintx, MaxHeapSize, calculated_heapsize);374_max_heap_byte_size = MaxHeapSize;375FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize);376_initial_heap_byte_size = InitialHeapSize;377}378379// adjust max heap size if necessary380if (NewSize + OldSize > MaxHeapSize) {381if (_max_heap_size_cmdline) {382// somebody set a maximum heap size with the intention that we should not383// exceed it. Adjust New/OldSize as necessary.384uintx calculated_size = NewSize + OldSize;385double shrink_factor = (double) MaxHeapSize / calculated_size;386uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment);387FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));388_initial_gen0_size = NewSize;389390// OldSize is already aligned because above we aligned MaxHeapSize to391// _heap_alignment, and we just made sure that NewSize is aligned to392// _gen_alignment. In initialize_flags() we verified that _heap_alignment393// is a multiple of _gen_alignment.394FLAG_SET_ERGO(uintx, OldSize, MaxHeapSize - NewSize);395} else {396FLAG_SET_ERGO(uintx, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));397_max_heap_byte_size = MaxHeapSize;398}399}400401always_do_update_barrier = UseConcMarkSweepGC;402403DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_flags();)404}405406// Values set on the command line win over any ergonomically407// set command line parameters.408// Ergonomic choice of parameters are done before this409// method is called. Values for command line parameters such as NewSize410// and MaxNewSize feed those ergonomic choices into this method.411// This method makes the final generation sizings consistent with412// themselves and with overall heap sizings.413// In the absence of explicitly set command line flags, policies414// such as the use of NewRatio are used to size the generation.415void GenCollectorPolicy::initialize_size_info() {416CollectorPolicy::initialize_size_info();417418// _space_alignment is used for alignment within a generation.419// There is additional alignment done down stream for some420// collectors that sometimes causes unwanted rounding up of421// generations sizes.422423// Determine maximum size of gen0424425size_t max_new_size = 0;426if (!FLAG_IS_DEFAULT(MaxNewSize)) {427max_new_size = MaxNewSize;428} else {429max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size);430// Bound the maximum size by NewSize below (since it historically431// would have been NewSize and because the NewRatio calculation could432// yield a size that is too small) and bound it by MaxNewSize above.433// Ergonomics plays here by previously calculating the desired434// NewSize and MaxNewSize.435max_new_size = MIN2(MAX2(max_new_size, NewSize), MaxNewSize);436}437assert(max_new_size > 0, "All paths should set max_new_size");438439// Given the maximum gen0 size, determine the initial and440// minimum gen0 sizes.441442if (_max_heap_byte_size == _min_heap_byte_size) {443// The maximum and minimum heap sizes are the same so444// the generations minimum and initial must be the445// same as its maximum.446_min_gen0_size = max_new_size;447_initial_gen0_size = max_new_size;448_max_gen0_size = max_new_size;449} else {450size_t desired_new_size = 0;451if (FLAG_IS_CMDLINE(NewSize)) {452// If NewSize is set on the command line, we must use it as453// the initial size and it also makes sense to use it as the454// lower limit.455_min_gen0_size = NewSize;456desired_new_size = NewSize;457max_new_size = MAX2(max_new_size, NewSize);458} else if (FLAG_IS_ERGO(NewSize)) {459// If NewSize is set ergonomically, we should use it as a lower460// limit, but use NewRatio to calculate the initial size.461_min_gen0_size = NewSize;462desired_new_size =463MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);464max_new_size = MAX2(max_new_size, NewSize);465} else {466// For the case where NewSize is the default, use NewRatio467// to size the minimum and initial generation sizes.468// Use the default NewSize as the floor for these values. If469// NewRatio is overly large, the resulting sizes can be too470// small.471_min_gen0_size = MAX2(scale_by_NewRatio_aligned(_min_heap_byte_size), NewSize);472desired_new_size =473MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);474}475476assert(_min_gen0_size > 0, "Sanity check");477_initial_gen0_size = desired_new_size;478_max_gen0_size = max_new_size;479480// At this point the desirable initial and minimum sizes have been481// determined without regard to the maximum sizes.482483// Bound the sizes by the corresponding overall heap sizes.484_min_gen0_size = bound_minus_alignment(_min_gen0_size, _min_heap_byte_size);485_initial_gen0_size = bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size);486_max_gen0_size = bound_minus_alignment(_max_gen0_size, _max_heap_byte_size);487488// At this point all three sizes have been checked against the489// maximum sizes but have not been checked for consistency490// among the three.491492// Final check min <= initial <= max493_min_gen0_size = MIN2(_min_gen0_size, _max_gen0_size);494_initial_gen0_size = MAX2(MIN2(_initial_gen0_size, _max_gen0_size), _min_gen0_size);495_min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size);496}497498// Write back to flags if necessary499if (NewSize != _initial_gen0_size) {500FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size);501}502503if (MaxNewSize != _max_gen0_size) {504FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size);505}506507if (PrintGCDetails && Verbose) {508gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 "509SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,510_min_gen0_size, _initial_gen0_size, _max_gen0_size);511}512513DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)514}515516// Call this method during the sizing of the gen1 to make517// adjustments to gen0 because of gen1 sizing policy. gen0 initially has518// the most freedom in sizing because it is done before the519// policy for gen1 is applied. Once gen1 policies have been applied,520// there may be conflicts in the shape of the heap and this method521// is used to make the needed adjustments. The application of the522// policies could be more sophisticated (iterative for example) but523// keeping it simple also seems a worthwhile goal.524bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr,525size_t* gen1_size_ptr,526const size_t heap_size) {527bool result = false;528529if ((*gen0_size_ptr + *gen1_size_ptr) > heap_size) {530uintx smallest_new_size = young_gen_size_lower_bound();531if ((heap_size < (*gen0_size_ptr + _min_gen1_size)) &&532(heap_size >= _min_gen1_size + smallest_new_size)) {533// Adjust gen0 down to accommodate _min_gen1_size534*gen0_size_ptr = align_size_down_bounded(heap_size - _min_gen1_size, _gen_alignment);535result = true;536} else {537*gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _gen_alignment);538}539}540return result;541}542543// Minimum sizes of the generations may be different than544// the initial sizes. An inconsistently is permitted here545// in the total size that can be specified explicitly by546// command line specification of OldSize and NewSize and547// also a command line specification of -Xms. Issue a warning548// but allow the values to pass.549550void TwoGenerationCollectorPolicy::initialize_size_info() {551GenCollectorPolicy::initialize_size_info();552553// At this point the minimum, initial and maximum sizes554// of the overall heap and of gen0 have been determined.555// The maximum gen1 size can be determined from the maximum gen0556// and maximum heap size since no explicit flags exits557// for setting the gen1 maximum.558_max_gen1_size = MAX2(_max_heap_byte_size - _max_gen0_size, _gen_alignment);559560// If no explicit command line flag has been set for the561// gen1 size, use what is left for gen1.562if (!FLAG_IS_CMDLINE(OldSize)) {563// The user has not specified any value but the ergonomics564// may have chosen a value (which may or may not be consistent565// with the overall heap size). In either case make566// the minimum, maximum and initial sizes consistent567// with the gen0 sizes and the overall heap sizes.568_min_gen1_size = MAX2(_min_heap_byte_size - _min_gen0_size, _gen_alignment);569_initial_gen1_size = MAX2(_initial_heap_byte_size - _initial_gen0_size, _gen_alignment);570// _max_gen1_size has already been made consistent above571FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);572} else {573// It's been explicitly set on the command line. Use the574// OldSize and then determine the consequences.575_min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size);576_initial_gen1_size = OldSize;577578// If the user has explicitly set an OldSize that is inconsistent579// with other command line flags, issue a warning.580// The generation minimums and the overall heap mimimum should581// be within one generation alignment.582if ((_min_gen1_size + _min_gen0_size + _gen_alignment) < _min_heap_byte_size) {583warning("Inconsistency between minimum heap size and minimum "584"generation sizes: using minimum heap = " SIZE_FORMAT,585_min_heap_byte_size);586}587if (OldSize > _max_gen1_size) {588warning("Inconsistency between maximum heap size and maximum "589"generation sizes: using maximum heap = " SIZE_FORMAT590" -XX:OldSize flag is being ignored",591_max_heap_byte_size);592}593// If there is an inconsistency between the OldSize and the minimum and/or594// initial size of gen0, since OldSize was explicitly set, OldSize wins.595if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size, _min_heap_byte_size)) {596if (PrintGCDetails && Verbose) {597gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 "598SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,599_min_gen0_size, _initial_gen0_size, _max_gen0_size);600}601}602// Initial size603if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,604_initial_heap_byte_size)) {605if (PrintGCDetails && Verbose) {606gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 "607SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,608_min_gen0_size, _initial_gen0_size, _max_gen0_size);609}610}611}612// Enforce the maximum gen1 size.613_min_gen1_size = MIN2(_min_gen1_size, _max_gen1_size);614615// Check that min gen1 <= initial gen1 <= max gen1616_initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size);617_initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size);618619// Write back to flags if necessary620if (NewSize != _initial_gen0_size) {621FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size);622}623624if (MaxNewSize != _max_gen0_size) {625FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size);626}627628if (OldSize != _initial_gen1_size) {629FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);630}631632if (PrintGCDetails && Verbose) {633gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 "634SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT,635_min_gen1_size, _initial_gen1_size, _max_gen1_size);636}637638DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_size_info();)639}640641HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,642bool is_tlab,643bool* gc_overhead_limit_was_exceeded) {644GenCollectedHeap *gch = GenCollectedHeap::heap();645646debug_only(gch->check_for_valid_allocation_state());647assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");648649// In general gc_overhead_limit_was_exceeded should be false so650// set it so here and reset it to true only if the gc time651// limit is being exceeded as checked below.652*gc_overhead_limit_was_exceeded = false;653654HeapWord* result = NULL;655656// Loop until the allocation is satisified,657// or unsatisfied after GC.658for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {659HandleMark hm; // discard any handles allocated in each iteration660661// First allocation attempt is lock-free.662Generation *gen0 = gch->get_gen(0);663assert(gen0->supports_inline_contig_alloc(),664"Otherwise, must do alloc within heap lock");665if (gen0->should_allocate(size, is_tlab)) {666result = gen0->par_allocate(size, is_tlab);667if (result != NULL) {668assert(gch->is_in_reserved(result), "result not in heap");669return result;670}671}672uint gc_count_before; // read inside the Heap_lock locked region673{674MutexLocker ml(Heap_lock);675if (PrintGC && Verbose) {676gclog_or_tty->print_cr("TwoGenerationCollectorPolicy::mem_allocate_work:"677" attempting locked slow path allocation");678}679// Note that only large objects get a shot at being680// allocated in later generations.681bool first_only = ! should_try_older_generation_allocation(size);682683result = gch->attempt_allocation(size, is_tlab, first_only);684if (result != NULL) {685assert(gch->is_in_reserved(result), "result not in heap");686return result;687}688689if (GC_locker::is_active_and_needs_gc()) {690if (is_tlab) {691return NULL; // Caller will retry allocating individual object692}693if (!gch->is_maximal_no_gc()) {694// Try and expand heap to satisfy request695result = expand_heap_and_allocate(size, is_tlab);696// result could be null if we are out of space697if (result != NULL) {698return result;699}700}701702if (gclocker_stalled_count > GCLockerRetryAllocationCount) {703return NULL; // we didn't get to do a GC and we didn't get any memory704}705706// If this thread is not in a jni critical section, we stall707// the requestor until the critical section has cleared and708// GC allowed. When the critical section clears, a GC is709// initiated by the last thread exiting the critical section; so710// we retry the allocation sequence from the beginning of the loop,711// rather than causing more, now probably unnecessary, GC attempts.712JavaThread* jthr = JavaThread::current();713if (!jthr->in_critical()) {714MutexUnlocker mul(Heap_lock);715// Wait for JNI critical section to be exited716GC_locker::stall_until_clear();717gclocker_stalled_count += 1;718continue;719} else {720if (CheckJNICalls) {721fatal("Possible deadlock due to allocating while"722" in jni critical section");723}724return NULL;725}726}727728// Read the gc count while the heap lock is held.729gc_count_before = Universe::heap()->total_collections();730}731732VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);733VMThread::execute(&op);734if (op.prologue_succeeded()) {735result = op.result();736if (op.gc_locked()) {737assert(result == NULL, "must be NULL if gc_locked() is true");738continue; // retry and/or stall as necessary739}740741// Allocation has failed and a collection742// has been done. If the gc time limit was exceeded the743// this time, return NULL so that an out-of-memory744// will be thrown. Clear gc_overhead_limit_exceeded745// so that the overhead exceeded does not persist.746747const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();748const bool softrefs_clear = all_soft_refs_clear();749750if (limit_exceeded && softrefs_clear) {751*gc_overhead_limit_was_exceeded = true;752size_policy()->set_gc_overhead_limit_exceeded(false);753if (op.result() != NULL) {754CollectedHeap::fill_with_object(op.result(), size);755}756return NULL;757}758assert(result == NULL || gch->is_in_reserved(result),759"result not in heap");760return result;761}762763// Give a warning if we seem to be looping forever.764if ((QueuedAllocationWarningCount > 0) &&765(try_count % QueuedAllocationWarningCount == 0)) {766warning("TwoGenerationCollectorPolicy::mem_allocate_work retries %d times \n\t"767" size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");768}769}770}771772HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size,773bool is_tlab) {774GenCollectedHeap *gch = GenCollectedHeap::heap();775HeapWord* result = NULL;776for (int i = number_of_generations() - 1; i >= 0 && result == NULL; i--) {777Generation *gen = gch->get_gen(i);778if (gen->should_allocate(size, is_tlab)) {779result = gen->expand_and_allocate(size, is_tlab);780}781}782assert(result == NULL || gch->is_in_reserved(result), "result not in heap");783return result;784}785786HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,787bool is_tlab) {788GenCollectedHeap *gch = GenCollectedHeap::heap();789GCCauseSetter x(gch, GCCause::_allocation_failure);790HeapWord* result = NULL;791792assert(size != 0, "Precondition violated");793if (GC_locker::is_active_and_needs_gc()) {794// GC locker is active; instead of a collection we will attempt795// to expand the heap, if there's room for expansion.796if (!gch->is_maximal_no_gc()) {797result = expand_heap_and_allocate(size, is_tlab);798}799return result; // could be null if we are out of space800} else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) {801// Do an incremental collection.802gch->do_collection(false /* full */,803false /* clear_all_soft_refs */,804size /* size */,805is_tlab /* is_tlab */,806number_of_generations() - 1 /* max_level */);807} else {808if (Verbose && PrintGCDetails) {809gclog_or_tty->print(" :: Trying full because partial may fail :: ");810}811// Try a full collection; see delta for bug id 6266275812// for the original code and why this has been simplified813// with from-space allocation criteria modified and814// such allocation moved out of the safepoint path.815gch->do_collection(true /* full */,816false /* clear_all_soft_refs */,817size /* size */,818is_tlab /* is_tlab */,819number_of_generations() - 1 /* max_level */);820}821822result = gch->attempt_allocation(size, is_tlab, false /*first_only*/);823824if (result != NULL) {825assert(gch->is_in_reserved(result), "result not in heap");826return result;827}828829// OK, collection failed, try expansion.830result = expand_heap_and_allocate(size, is_tlab);831if (result != NULL) {832return result;833}834835// If we reach this point, we're really out of memory. Try every trick836// we can to reclaim memory. Force collection of soft references. Force837// a complete compaction of the heap. Any additional methods for finding838// free memory should be here, especially if they are expensive. If this839// attempt fails, an OOM exception will be thrown.840{841UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted842843gch->do_collection(true /* full */,844true /* clear_all_soft_refs */,845size /* size */,846is_tlab /* is_tlab */,847number_of_generations() - 1 /* max_level */);848}849850result = gch->attempt_allocation(size, is_tlab, false /* first_only */);851if (result != NULL) {852assert(gch->is_in_reserved(result), "result not in heap");853return result;854}855856assert(!should_clear_all_soft_refs(),857"Flag should have been handled and cleared prior to this point");858859// What else? We might try synchronous finalization later. If the total860// space available is large enough for the allocation, then a more861// complete compaction phase than we've tried so far might be862// appropriate.863return NULL;864}865866MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(867ClassLoaderData* loader_data,868size_t word_size,869Metaspace::MetadataType mdtype) {870uint loop_count = 0;871uint gc_count = 0;872uint full_gc_count = 0;873874assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");875876do {877MetaWord* result = NULL;878if (GC_locker::is_active_and_needs_gc()) {879// If the GC_locker is active, just expand and allocate.880// If that does not succeed, wait if this thread is not881// in a critical section itself.882result =883loader_data->metaspace_non_null()->expand_and_allocate(word_size,884mdtype);885if (result != NULL) {886return result;887}888JavaThread* jthr = JavaThread::current();889if (!jthr->in_critical()) {890// Wait for JNI critical section to be exited891GC_locker::stall_until_clear();892// The GC invoked by the last thread leaving the critical893// section will be a young collection and a full collection894// is (currently) needed for unloading classes so continue895// to the next iteration to get a full GC.896continue;897} else {898if (CheckJNICalls) {899fatal("Possible deadlock due to allocating while"900" in jni critical section");901}902return NULL;903}904}905906{ // Need lock to get self consistent gc_count's907MutexLocker ml(Heap_lock);908gc_count = Universe::heap()->total_collections();909full_gc_count = Universe::heap()->total_full_collections();910}911912// Generate a VM operation913VM_CollectForMetadataAllocation op(loader_data,914word_size,915mdtype,916gc_count,917full_gc_count,918GCCause::_metadata_GC_threshold);919VMThread::execute(&op);920921// If GC was locked out, try again. Check922// before checking success because the prologue923// could have succeeded and the GC still have924// been locked out.925if (op.gc_locked()) {926continue;927}928929if (op.prologue_succeeded()) {930return op.result();931}932loop_count++;933if ((QueuedAllocationWarningCount > 0) &&934(loop_count % QueuedAllocationWarningCount == 0)) {935warning("satisfy_failed_metadata_allocation() retries %d times \n\t"936" size=" SIZE_FORMAT, loop_count, word_size);937}938} while (true); // Until a GC is done939}940941// Return true if any of the following is true:942// . the allocation won't fit into the current young gen heap943// . gc locker is occupied (jni critical section)944// . heap memory is tight -- the most recent previous collection945// was a full collection because a partial collection (would946// have) failed and is likely to fail again947bool GenCollectorPolicy::should_try_older_generation_allocation(948size_t word_size) const {949GenCollectedHeap* gch = GenCollectedHeap::heap();950size_t gen0_capacity = gch->get_gen(0)->capacity_before_gc();951return (word_size > heap_word_size(gen0_capacity))952|| GC_locker::is_active_and_needs_gc()953|| gch->incremental_collection_failed();954}955956957//958// MarkSweepPolicy methods959//960961void MarkSweepPolicy::initialize_alignments() {962_space_alignment = _gen_alignment = (uintx)Generation::GenGrain;963_heap_alignment = compute_heap_alignment();964}965966void MarkSweepPolicy::initialize_generations() {967_generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, CURRENT_PC,968AllocFailStrategy::RETURN_NULL);969if (_generations == NULL) {970vm_exit_during_initialization("Unable to allocate gen spec");971}972973if (UseParNewGC) {974_generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size);975} else {976_generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size);977}978_generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_gen1_size, _max_gen1_size);979980if (_generations[0] == NULL || _generations[1] == NULL) {981vm_exit_during_initialization("Unable to allocate gen spec");982}983}984985void MarkSweepPolicy::initialize_gc_policy_counters() {986// initialize the policy counters - 2 collectors, 3 generations987if (UseParNewGC) {988_gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3);989} else {990_gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);991}992}993994/////////////// Unit tests ///////////////995996#ifndef PRODUCT997// Testing that the NewSize flag is handled correct is hard because it998// depends on so many other configurable variables. This test only tries to999// verify that there are some basic rules for NewSize honored by the policies.1000class TestGenCollectorPolicy {1001public:1002static void test() {1003size_t flag_value;10041005save_flags();10061007// Set some limits that makes the math simple.1008FLAG_SET_ERGO(uintx, MaxHeapSize, 180 * M);1009FLAG_SET_ERGO(uintx, InitialHeapSize, 120 * M);1010Arguments::set_min_heap_size(40 * M);10111012// If NewSize is set on the command line, it should be used1013// for both min and initial young size if less than min heap.1014flag_value = 20 * M;1015FLAG_SET_CMDLINE(uintx, NewSize, flag_value);1016verify_min(flag_value);1017verify_initial(flag_value);10181019// If NewSize is set on command line, but is larger than the min1020// heap size, it should only be used for initial young size.1021flag_value = 80 * M;1022FLAG_SET_CMDLINE(uintx, NewSize, flag_value);1023verify_initial(flag_value);10241025// If NewSize has been ergonomically set, the collector policy1026// should use it for min but calculate the initial young size1027// using NewRatio.1028flag_value = 20 * M;1029FLAG_SET_ERGO(uintx, NewSize, flag_value);1030verify_min(flag_value);1031verify_scaled_initial(InitialHeapSize);10321033restore_flags();10341035}10361037static void verify_min(size_t expected) {1038MarkSweepPolicy msp;1039msp.initialize_all();10401041assert(msp.min_gen0_size() <= expected, err_msg("%zu > %zu", msp.min_gen0_size(), expected));1042}10431044static void verify_initial(size_t expected) {1045MarkSweepPolicy msp;1046msp.initialize_all();10471048assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected));1049}10501051static void verify_scaled_initial(size_t initial_heap_size) {1052MarkSweepPolicy msp;1053msp.initialize_all();10541055size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size);1056assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected));1057assert(FLAG_IS_ERGO(NewSize) && NewSize == expected,1058err_msg("NewSize should have been set ergonomically to %zu, but was %zu", expected, NewSize));1059}10601061private:1062static size_t original_InitialHeapSize;1063static size_t original_MaxHeapSize;1064static size_t original_MaxNewSize;1065static size_t original_MinHeapDeltaBytes;1066static size_t original_NewSize;1067static size_t original_OldSize;10681069static void save_flags() {1070original_InitialHeapSize = InitialHeapSize;1071original_MaxHeapSize = MaxHeapSize;1072original_MaxNewSize = MaxNewSize;1073original_MinHeapDeltaBytes = MinHeapDeltaBytes;1074original_NewSize = NewSize;1075original_OldSize = OldSize;1076}10771078static void restore_flags() {1079InitialHeapSize = original_InitialHeapSize;1080MaxHeapSize = original_MaxHeapSize;1081MaxNewSize = original_MaxNewSize;1082MinHeapDeltaBytes = original_MinHeapDeltaBytes;1083NewSize = original_NewSize;1084OldSize = original_OldSize;1085}1086};10871088size_t TestGenCollectorPolicy::original_InitialHeapSize = 0;1089size_t TestGenCollectorPolicy::original_MaxHeapSize = 0;1090size_t TestGenCollectorPolicy::original_MaxNewSize = 0;1091size_t TestGenCollectorPolicy::original_MinHeapDeltaBytes = 0;1092size_t TestGenCollectorPolicy::original_NewSize = 0;1093size_t TestGenCollectorPolicy::original_OldSize = 0;10941095void TestNewSize_test() {1096TestGenCollectorPolicy::test();1097}10981099#endif110011011102