8016309: assert(eden_size > 0 && survivor_size > 0) failed: just checking
7057939: jmap shows MaxNewSize=4GB when Java is using parallel collector Major cleanup of the collectorpolicy classes Reviewed-by: tschatzl, jcoomes
This commit is contained in:
parent
9705a6e3f9
commit
0fa3a71c8a
@ -47,8 +47,9 @@
|
|||||||
// ConcurrentMarkSweepPolicy methods
|
// ConcurrentMarkSweepPolicy methods
|
||||||
//
|
//
|
||||||
|
|
||||||
ConcurrentMarkSweepPolicy::ConcurrentMarkSweepPolicy() {
|
void ConcurrentMarkSweepPolicy::initialize_alignments() {
|
||||||
initialize_all();
|
_space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
|
||||||
|
_heap_alignment = compute_heap_alignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentMarkSweepPolicy::initialize_generations() {
|
void ConcurrentMarkSweepPolicy::initialize_generations() {
|
||||||
|
@ -29,10 +29,11 @@
|
|||||||
|
|
||||||
class ConcurrentMarkSweepPolicy : public TwoGenerationCollectorPolicy {
|
class ConcurrentMarkSweepPolicy : public TwoGenerationCollectorPolicy {
|
||||||
protected:
|
protected:
|
||||||
|
void initialize_alignments();
|
||||||
void initialize_generations();
|
void initialize_generations();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConcurrentMarkSweepPolicy();
|
ConcurrentMarkSweepPolicy() {}
|
||||||
|
|
||||||
ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return this; }
|
ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return this; }
|
||||||
|
|
||||||
|
@ -2008,7 +2008,7 @@ jint G1CollectedHeap::initialize() {
|
|||||||
|
|
||||||
size_t init_byte_size = collector_policy()->initial_heap_byte_size();
|
size_t init_byte_size = collector_policy()->initial_heap_byte_size();
|
||||||
size_t max_byte_size = collector_policy()->max_heap_byte_size();
|
size_t max_byte_size = collector_policy()->max_heap_byte_size();
|
||||||
size_t heap_alignment = collector_policy()->max_alignment();
|
size_t heap_alignment = collector_policy()->heap_alignment();
|
||||||
|
|
||||||
// Ensure that the sizes are properly aligned.
|
// Ensure that the sizes are properly aligned.
|
||||||
Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
|
Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
|
||||||
|
@ -313,27 +313,38 @@ G1CollectorPolicy::G1CollectorPolicy() :
|
|||||||
// for the first time during initialization.
|
// for the first time during initialization.
|
||||||
_reserve_regions = 0;
|
_reserve_regions = 0;
|
||||||
|
|
||||||
initialize_all();
|
|
||||||
_collectionSetChooser = new CollectionSetChooser();
|
_collectionSetChooser = new CollectionSetChooser();
|
||||||
_young_gen_sizer = new G1YoungGenSizer(); // Must be after call to initialize_flags
|
}
|
||||||
|
|
||||||
|
void G1CollectorPolicy::initialize_alignments() {
|
||||||
|
_space_alignment = HeapRegion::GrainBytes;
|
||||||
|
size_t card_table_alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
|
||||||
|
size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
|
||||||
|
_heap_alignment = MAX3(card_table_alignment, _space_alignment, page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1CollectorPolicy::initialize_flags() {
|
void G1CollectorPolicy::initialize_flags() {
|
||||||
_min_alignment = HeapRegion::GrainBytes;
|
if (G1HeapRegionSize != HeapRegion::GrainBytes) {
|
||||||
size_t card_table_alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
|
FLAG_SET_ERGO(uintx, G1HeapRegionSize, HeapRegion::GrainBytes);
|
||||||
size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
|
}
|
||||||
_max_alignment = MAX3(card_table_alignment, _min_alignment, page_size);
|
|
||||||
if (SurvivorRatio < 1) {
|
if (SurvivorRatio < 1) {
|
||||||
vm_exit_during_initialization("Invalid survivor ratio specified");
|
vm_exit_during_initialization("Invalid survivor ratio specified");
|
||||||
}
|
}
|
||||||
CollectorPolicy::initialize_flags();
|
CollectorPolicy::initialize_flags();
|
||||||
|
_young_gen_sizer = new G1YoungGenSizer(); // Must be after call to initialize_flags
|
||||||
}
|
}
|
||||||
|
|
||||||
G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true) {
|
void G1CollectorPolicy::post_heap_initialize() {
|
||||||
assert(G1NewSizePercent <= G1MaxNewSizePercent, "Min larger than max");
|
uintx max_regions = G1CollectedHeap::heap()->max_regions();
|
||||||
assert(G1NewSizePercent > 0 && G1NewSizePercent < 100, "Min out of bounds");
|
size_t max_young_size = (size_t)_young_gen_sizer->max_young_length(max_regions) * HeapRegion::GrainBytes;
|
||||||
assert(G1MaxNewSizePercent > 0 && G1MaxNewSizePercent < 100, "Max out of bounds");
|
if (max_young_size != MaxNewSize) {
|
||||||
|
FLAG_SET_ERGO(uintx, MaxNewSize, max_young_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true),
|
||||||
|
_min_desired_young_length(0), _max_desired_young_length(0) {
|
||||||
if (FLAG_IS_CMDLINE(NewRatio)) {
|
if (FLAG_IS_CMDLINE(NewRatio)) {
|
||||||
if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
|
if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
|
||||||
warning("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
|
warning("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
|
||||||
@ -344,8 +355,13 @@ G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAG_IS_CMDLINE(NewSize) && FLAG_IS_CMDLINE(MaxNewSize) && NewSize > MaxNewSize) {
|
if (NewSize > MaxNewSize) {
|
||||||
vm_exit_during_initialization("Initial young gen size set larger than the maximum young gen size");
|
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);
|
||||||
|
}
|
||||||
|
MaxNewSize = NewSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAG_IS_CMDLINE(NewSize)) {
|
if (FLAG_IS_CMDLINE(NewSize)) {
|
||||||
@ -378,34 +394,48 @@ uint G1YoungGenSizer::calculate_default_max_length(uint new_number_of_heap_regio
|
|||||||
return MAX2(1U, default_value);
|
return MAX2(1U, default_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1YoungGenSizer::heap_size_changed(uint new_number_of_heap_regions) {
|
void G1YoungGenSizer::recalculate_min_max_young_length(uint number_of_heap_regions, uint* min_young_length, uint* max_young_length) {
|
||||||
assert(new_number_of_heap_regions > 0, "Heap must be initialized");
|
assert(number_of_heap_regions > 0, "Heap must be initialized");
|
||||||
|
|
||||||
switch (_sizer_kind) {
|
switch (_sizer_kind) {
|
||||||
case SizerDefaults:
|
case SizerDefaults:
|
||||||
_min_desired_young_length = calculate_default_min_length(new_number_of_heap_regions);
|
*min_young_length = calculate_default_min_length(number_of_heap_regions);
|
||||||
_max_desired_young_length = calculate_default_max_length(new_number_of_heap_regions);
|
*max_young_length = calculate_default_max_length(number_of_heap_regions);
|
||||||
break;
|
break;
|
||||||
case SizerNewSizeOnly:
|
case SizerNewSizeOnly:
|
||||||
_max_desired_young_length = calculate_default_max_length(new_number_of_heap_regions);
|
*max_young_length = calculate_default_max_length(number_of_heap_regions);
|
||||||
_max_desired_young_length = MAX2(_min_desired_young_length, _max_desired_young_length);
|
*max_young_length = MAX2(*min_young_length, *max_young_length);
|
||||||
break;
|
break;
|
||||||
case SizerMaxNewSizeOnly:
|
case SizerMaxNewSizeOnly:
|
||||||
_min_desired_young_length = calculate_default_min_length(new_number_of_heap_regions);
|
*min_young_length = calculate_default_min_length(number_of_heap_regions);
|
||||||
_min_desired_young_length = MIN2(_min_desired_young_length, _max_desired_young_length);
|
*min_young_length = MIN2(*min_young_length, *max_young_length);
|
||||||
break;
|
break;
|
||||||
case SizerMaxAndNewSize:
|
case SizerMaxAndNewSize:
|
||||||
// Do nothing. Values set on the command line, don't update them at runtime.
|
// Do nothing. Values set on the command line, don't update them at runtime.
|
||||||
break;
|
break;
|
||||||
case SizerNewRatio:
|
case SizerNewRatio:
|
||||||
_min_desired_young_length = new_number_of_heap_regions / (NewRatio + 1);
|
*min_young_length = number_of_heap_regions / (NewRatio + 1);
|
||||||
_max_desired_young_length = _min_desired_young_length;
|
*max_young_length = *min_young_length;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values");
|
assert(*min_young_length <= *max_young_length, "Invalid min/max young gen size values");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint G1YoungGenSizer::max_young_length(uint number_of_heap_regions) {
|
||||||
|
// We need to pass the desired values because recalculation may not update these
|
||||||
|
// values in some cases.
|
||||||
|
uint temp = _min_desired_young_length;
|
||||||
|
uint result = _max_desired_young_length;
|
||||||
|
recalculate_min_max_young_length(number_of_heap_regions, &temp, &result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G1YoungGenSizer::heap_size_changed(uint new_number_of_heap_regions) {
|
||||||
|
recalculate_min_max_young_length(new_number_of_heap_regions, &_min_desired_young_length,
|
||||||
|
&_max_desired_young_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1CollectorPolicy::init() {
|
void G1CollectorPolicy::init() {
|
||||||
|
@ -136,8 +136,16 @@ private:
|
|||||||
uint calculate_default_min_length(uint new_number_of_heap_regions);
|
uint calculate_default_min_length(uint new_number_of_heap_regions);
|
||||||
uint calculate_default_max_length(uint new_number_of_heap_regions);
|
uint calculate_default_max_length(uint new_number_of_heap_regions);
|
||||||
|
|
||||||
|
// Update the given values for minimum and maximum young gen length in regions
|
||||||
|
// given the number of heap regions depending on the kind of sizing algorithm.
|
||||||
|
void recalculate_min_max_young_length(uint number_of_heap_regions, uint* min_young_length, uint* max_young_length);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
G1YoungGenSizer();
|
G1YoungGenSizer();
|
||||||
|
// Calculate the maximum length of the young gen given the number of regions
|
||||||
|
// depending on the sizing algorithm.
|
||||||
|
uint max_young_length(uint number_of_heap_regions);
|
||||||
|
|
||||||
void heap_size_changed(uint new_number_of_heap_regions);
|
void heap_size_changed(uint new_number_of_heap_regions);
|
||||||
uint min_desired_young_length() {
|
uint min_desired_young_length() {
|
||||||
return _min_desired_young_length;
|
return _min_desired_young_length;
|
||||||
@ -165,13 +173,9 @@ private:
|
|||||||
|
|
||||||
G1MMUTracker* _mmu_tracker;
|
G1MMUTracker* _mmu_tracker;
|
||||||
|
|
||||||
|
void initialize_alignments();
|
||||||
void initialize_flags();
|
void initialize_flags();
|
||||||
|
|
||||||
void initialize_all() {
|
|
||||||
initialize_flags();
|
|
||||||
initialize_size_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
CollectionSetChooser* _collectionSetChooser;
|
CollectionSetChooser* _collectionSetChooser;
|
||||||
|
|
||||||
double _full_collection_start_sec;
|
double _full_collection_start_sec;
|
||||||
@ -931,6 +935,7 @@ public:
|
|||||||
// Calculates survivor space parameters.
|
// Calculates survivor space parameters.
|
||||||
void update_survivors_policy();
|
void update_survivors_policy();
|
||||||
|
|
||||||
|
virtual void post_heap_initialize();
|
||||||
};
|
};
|
||||||
|
|
||||||
// This should move to some place more general...
|
// This should move to some place more general...
|
||||||
|
@ -174,11 +174,6 @@ void HeapRegion::setup_heap_region_size(size_t initial_heap_size, size_t max_hea
|
|||||||
region_size = MAX_REGION_SIZE;
|
region_size = MAX_REGION_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region_size != G1HeapRegionSize) {
|
|
||||||
// Update the flag to make sure that PrintFlagsFinal logs the correct value
|
|
||||||
FLAG_SET_ERGO(uintx, G1HeapRegionSize, region_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// And recalculate the log.
|
// And recalculate the log.
|
||||||
region_size_log = log2_long((jlong) region_size);
|
region_size_log = log2_long((jlong) region_size);
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/adjoiningGenerations.hpp"
|
#include "gc_implementation/parallelScavenge/adjoiningGenerations.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp"
|
#include "gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp"
|
||||||
|
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
|
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
|
||||||
|
|
||||||
// If boundary moving is being used, create the young gen and old
|
// If boundary moving is being used, create the young gen and old
|
||||||
@ -32,15 +33,17 @@
|
|||||||
// the old behavior otherwise (with PSYoungGen and PSOldGen).
|
// the old behavior otherwise (with PSYoungGen and PSOldGen).
|
||||||
|
|
||||||
AdjoiningGenerations::AdjoiningGenerations(ReservedSpace old_young_rs,
|
AdjoiningGenerations::AdjoiningGenerations(ReservedSpace old_young_rs,
|
||||||
size_t init_low_byte_size,
|
GenerationSizer* policy,
|
||||||
size_t min_low_byte_size,
|
|
||||||
size_t max_low_byte_size,
|
|
||||||
size_t init_high_byte_size,
|
|
||||||
size_t min_high_byte_size,
|
|
||||||
size_t max_high_byte_size,
|
|
||||||
size_t alignment) :
|
size_t alignment) :
|
||||||
_virtual_spaces(old_young_rs, min_low_byte_size,
|
_virtual_spaces(old_young_rs, policy->min_gen1_size(),
|
||||||
min_high_byte_size, alignment) {
|
policy->min_gen0_size(), alignment) {
|
||||||
|
size_t init_low_byte_size = policy->initial_gen1_size();
|
||||||
|
size_t min_low_byte_size = policy->min_gen1_size();
|
||||||
|
size_t max_low_byte_size = policy->max_gen1_size();
|
||||||
|
size_t init_high_byte_size = policy->initial_gen0_size();
|
||||||
|
size_t min_high_byte_size = policy->min_gen0_size();
|
||||||
|
size_t max_high_byte_size = policy->max_gen0_size();
|
||||||
|
|
||||||
assert(min_low_byte_size <= init_low_byte_size &&
|
assert(min_low_byte_size <= init_low_byte_size &&
|
||||||
init_low_byte_size <= max_low_byte_size, "Parameter check");
|
init_low_byte_size <= max_low_byte_size, "Parameter check");
|
||||||
assert(min_high_byte_size <= init_high_byte_size &&
|
assert(min_high_byte_size <= init_high_byte_size &&
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp"
|
#include "gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/asPSOldGen.hpp"
|
#include "gc_implementation/parallelScavenge/asPSOldGen.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/asPSYoungGen.hpp"
|
#include "gc_implementation/parallelScavenge/asPSYoungGen.hpp"
|
||||||
|
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
||||||
|
|
||||||
|
|
||||||
// Contains two generations that both use an AdjoiningVirtualSpaces.
|
// Contains two generations that both use an AdjoiningVirtualSpaces.
|
||||||
@ -56,14 +57,7 @@ class AdjoiningGenerations : public CHeapObj<mtGC> {
|
|||||||
bool request_young_gen_expansion(size_t desired_change_in_bytes);
|
bool request_young_gen_expansion(size_t desired_change_in_bytes);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AdjoiningGenerations(ReservedSpace rs,
|
AdjoiningGenerations(ReservedSpace rs, GenerationSizer* policy, size_t alignment);
|
||||||
size_t init_low_byte_size,
|
|
||||||
size_t min_low_byte_size,
|
|
||||||
size_t max_low_byte_size,
|
|
||||||
size_t init_high_byte_size,
|
|
||||||
size_t min_high_byte_size,
|
|
||||||
size_t max_high_bytes_size,
|
|
||||||
size_t alignment);
|
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
PSYoungGen* young_gen() { return _young_gen; }
|
PSYoungGen* young_gen() { return _young_gen; }
|
||||||
|
@ -91,7 +91,7 @@ size_t ASPSOldGen::available_for_expansion() {
|
|||||||
|
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
size_t result = gen_size_limit() - virtual_space()->committed_size();
|
size_t result = gen_size_limit() - virtual_space()->committed_size();
|
||||||
size_t result_aligned = align_size_down(result, heap->old_gen_alignment());
|
size_t result_aligned = align_size_down(result, heap->generation_alignment());
|
||||||
return result_aligned;
|
return result_aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ size_t ASPSOldGen::available_for_contraction() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
const size_t gen_alignment = heap->old_gen_alignment();
|
const size_t gen_alignment = heap->generation_alignment();
|
||||||
PSAdaptiveSizePolicy* policy = heap->size_policy();
|
PSAdaptiveSizePolicy* policy = heap->size_policy();
|
||||||
const size_t working_size =
|
const size_t working_size =
|
||||||
used_in_bytes() + (size_t) policy->avg_promoted()->padded_average();
|
used_in_bytes() + (size_t) policy->avg_promoted()->padded_average();
|
||||||
|
@ -75,7 +75,7 @@ size_t ASPSYoungGen::available_for_expansion() {
|
|||||||
"generation size limit is wrong");
|
"generation size limit is wrong");
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
size_t result = gen_size_limit() - current_committed_size;
|
size_t result = gen_size_limit() - current_committed_size;
|
||||||
size_t result_aligned = align_size_down(result, heap->young_gen_alignment());
|
size_t result_aligned = align_size_down(result, heap->generation_alignment());
|
||||||
return result_aligned;
|
return result_aligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,8 +92,8 @@ size_t ASPSYoungGen::available_for_contraction() {
|
|||||||
if (eden_space()->is_empty()) {
|
if (eden_space()->is_empty()) {
|
||||||
// Respect the minimum size for eden and for the young gen as a whole.
|
// Respect the minimum size for eden and for the young gen as a whole.
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
const size_t eden_alignment = heap->intra_heap_alignment();
|
const size_t eden_alignment = heap->space_alignment();
|
||||||
const size_t gen_alignment = heap->young_gen_alignment();
|
const size_t gen_alignment = heap->generation_alignment();
|
||||||
|
|
||||||
assert(eden_space()->capacity_in_bytes() >= eden_alignment,
|
assert(eden_space()->capacity_in_bytes() >= eden_alignment,
|
||||||
"Alignment is wrong");
|
"Alignment is wrong");
|
||||||
@ -129,7 +129,7 @@ size_t ASPSYoungGen::available_for_contraction() {
|
|||||||
// to_space can be.
|
// to_space can be.
|
||||||
size_t ASPSYoungGen::available_to_live() {
|
size_t ASPSYoungGen::available_to_live() {
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
const size_t alignment = heap->intra_heap_alignment();
|
const size_t alignment = heap->space_alignment();
|
||||||
|
|
||||||
// Include any space that is committed but is not in eden.
|
// Include any space that is committed but is not in eden.
|
||||||
size_t available = pointer_delta(eden_space()->bottom(),
|
size_t available = pointer_delta(eden_space()->bottom(),
|
||||||
@ -293,7 +293,7 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
|
|||||||
assert(eden_start < from_start, "Cannot push into from_space");
|
assert(eden_start < from_start, "Cannot push into from_space");
|
||||||
|
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
const size_t alignment = heap->intra_heap_alignment();
|
const size_t alignment = heap->space_alignment();
|
||||||
const bool maintain_minimum =
|
const bool maintain_minimum =
|
||||||
(requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
|
(requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
|
||||||
|
|
||||||
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.hpp"
|
||||||
|
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
||||||
|
#include "memory/collectorPolicy.hpp"
|
||||||
|
|
||||||
|
void GenerationSizer::trace_gen_sizes(const char* const str) {
|
||||||
|
if (TracePageSizes) {
|
||||||
|
tty->print_cr("%s: " SIZE_FORMAT "," SIZE_FORMAT " "
|
||||||
|
SIZE_FORMAT "," SIZE_FORMAT " "
|
||||||
|
SIZE_FORMAT,
|
||||||
|
str,
|
||||||
|
_min_gen1_size / K, _max_gen1_size / K,
|
||||||
|
_min_gen0_size / K, _max_gen0_size / K,
|
||||||
|
_max_heap_byte_size / K);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerationSizer::initialize_alignments() {
|
||||||
|
_space_alignment = _gen_alignment = default_gen_alignment();
|
||||||
|
_heap_alignment = compute_heap_alignment();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerationSizer::initialize_flags() {
|
||||||
|
// Do basic sizing work
|
||||||
|
TwoGenerationCollectorPolicy::initialize_flags();
|
||||||
|
|
||||||
|
assert(UseSerialGC ||
|
||||||
|
!FLAG_IS_DEFAULT(ParallelGCThreads) ||
|
||||||
|
(ParallelGCThreads > 0),
|
||||||
|
"ParallelGCThreads should be set before flag initialization");
|
||||||
|
|
||||||
|
// The survivor ratio's are calculated "raw", unlike the
|
||||||
|
// default gc, which adds 2 to the ratio value. We need to
|
||||||
|
// make sure the values are valid before using them.
|
||||||
|
if (MinSurvivorRatio < 3) {
|
||||||
|
FLAG_SET_ERGO(uintx, MinSurvivorRatio, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InitialSurvivorRatio < 3) {
|
||||||
|
FLAG_SET_ERGO(uintx, InitialSurvivorRatio, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerationSizer::initialize_size_info() {
|
||||||
|
trace_gen_sizes("ps heap raw");
|
||||||
|
const size_t page_sz = os::page_size_for_region(_min_heap_byte_size,
|
||||||
|
_max_heap_byte_size,
|
||||||
|
8);
|
||||||
|
|
||||||
|
// Can a page size be something else than a power of two?
|
||||||
|
assert(is_power_of_2((intptr_t)page_sz), "must be a power of 2");
|
||||||
|
size_t new_alignment = round_to(page_sz, _gen_alignment);
|
||||||
|
if (new_alignment != _gen_alignment) {
|
||||||
|
_gen_alignment = new_alignment;
|
||||||
|
// Redo everything from the start
|
||||||
|
initialize_flags();
|
||||||
|
}
|
||||||
|
TwoGenerationCollectorPolicy::initialize_size_info();
|
||||||
|
|
||||||
|
trace_gen_sizes("ps heap rnd");
|
||||||
|
}
|
@ -31,41 +31,17 @@
|
|||||||
// TwoGenerationCollectorPolicy. Lets reuse it!
|
// TwoGenerationCollectorPolicy. Lets reuse it!
|
||||||
|
|
||||||
class GenerationSizer : public TwoGenerationCollectorPolicy {
|
class GenerationSizer : public TwoGenerationCollectorPolicy {
|
||||||
public:
|
private:
|
||||||
GenerationSizer() {
|
|
||||||
// Partial init only!
|
|
||||||
initialize_flags();
|
|
||||||
initialize_size_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
void initialize_flags() {
|
void trace_gen_sizes(const char* const str);
|
||||||
// Do basic sizing work
|
|
||||||
TwoGenerationCollectorPolicy::initialize_flags();
|
|
||||||
|
|
||||||
assert(UseSerialGC ||
|
// The alignment used for boundary between young gen and old gen
|
||||||
!FLAG_IS_DEFAULT(ParallelGCThreads) ||
|
static size_t default_gen_alignment() { return 64 * K * HeapWordSize; }
|
||||||
(ParallelGCThreads > 0),
|
|
||||||
"ParallelGCThreads should be set before flag initialization");
|
|
||||||
|
|
||||||
// The survivor ratio's are calculated "raw", unlike the
|
protected:
|
||||||
// default gc, which adds 2 to the ratio value. We need to
|
|
||||||
// make sure the values are valid before using them.
|
|
||||||
if (MinSurvivorRatio < 3) {
|
|
||||||
MinSurvivorRatio = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InitialSurvivorRatio < 3) {
|
void initialize_alignments();
|
||||||
InitialSurvivorRatio = 3;
|
void initialize_flags();
|
||||||
}
|
void initialize_size_info();
|
||||||
}
|
|
||||||
|
|
||||||
size_t min_young_gen_size() { return _min_gen0_size; }
|
|
||||||
size_t young_gen_size() { return _initial_gen0_size; }
|
|
||||||
size_t max_young_gen_size() { return _max_gen0_size; }
|
|
||||||
|
|
||||||
size_t min_old_gen_size() { return _min_gen1_size; }
|
|
||||||
size_t old_gen_size() { return _initial_gen1_size; }
|
|
||||||
size_t max_old_gen_size() { return _max_gen1_size; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GENERATIONSIZER_HPP
|
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_GENERATIONSIZER_HPP
|
||||||
|
@ -52,76 +52,20 @@ PSGCAdaptivePolicyCounters* ParallelScavengeHeap::_gc_policy_counters = NULL;
|
|||||||
ParallelScavengeHeap* ParallelScavengeHeap::_psh = NULL;
|
ParallelScavengeHeap* ParallelScavengeHeap::_psh = NULL;
|
||||||
GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
|
GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
|
||||||
|
|
||||||
static void trace_gen_sizes(const char* const str,
|
|
||||||
size_t og_min, size_t og_max,
|
|
||||||
size_t yg_min, size_t yg_max)
|
|
||||||
{
|
|
||||||
if (TracePageSizes) {
|
|
||||||
tty->print_cr("%s: " SIZE_FORMAT "," SIZE_FORMAT " "
|
|
||||||
SIZE_FORMAT "," SIZE_FORMAT " "
|
|
||||||
SIZE_FORMAT,
|
|
||||||
str,
|
|
||||||
og_min / K, og_max / K,
|
|
||||||
yg_min / K, yg_max / K,
|
|
||||||
(og_max + yg_max) / K);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jint ParallelScavengeHeap::initialize() {
|
jint ParallelScavengeHeap::initialize() {
|
||||||
CollectedHeap::pre_initialize();
|
CollectedHeap::pre_initialize();
|
||||||
|
|
||||||
// Cannot be initialized until after the flags are parsed
|
// Initialize collector policy
|
||||||
// GenerationSizer flag_parser;
|
|
||||||
_collector_policy = new GenerationSizer();
|
_collector_policy = new GenerationSizer();
|
||||||
|
_collector_policy->initialize_all();
|
||||||
|
|
||||||
size_t yg_min_size = _collector_policy->min_young_gen_size();
|
const size_t heap_size = _collector_policy->max_heap_byte_size();
|
||||||
size_t yg_max_size = _collector_policy->max_young_gen_size();
|
|
||||||
size_t og_min_size = _collector_policy->min_old_gen_size();
|
|
||||||
size_t og_max_size = _collector_policy->max_old_gen_size();
|
|
||||||
|
|
||||||
trace_gen_sizes("ps heap raw",
|
|
||||||
og_min_size, og_max_size,
|
|
||||||
yg_min_size, yg_max_size);
|
|
||||||
|
|
||||||
const size_t og_page_sz = os::page_size_for_region(yg_min_size + og_min_size,
|
|
||||||
yg_max_size + og_max_size,
|
|
||||||
8);
|
|
||||||
|
|
||||||
const size_t og_align = set_alignment(_old_gen_alignment, og_page_sz);
|
|
||||||
const size_t yg_align = set_alignment(_young_gen_alignment, og_page_sz);
|
|
||||||
|
|
||||||
// Update sizes to reflect the selected page size(s).
|
|
||||||
//
|
|
||||||
// NEEDS_CLEANUP. The default TwoGenerationCollectorPolicy uses NewRatio; it
|
|
||||||
// should check UseAdaptiveSizePolicy. Changes from generationSizer could
|
|
||||||
// move to the common code.
|
|
||||||
yg_min_size = align_size_up(yg_min_size, yg_align);
|
|
||||||
yg_max_size = align_size_up(yg_max_size, yg_align);
|
|
||||||
size_t yg_cur_size =
|
|
||||||
align_size_up(_collector_policy->young_gen_size(), yg_align);
|
|
||||||
yg_cur_size = MAX2(yg_cur_size, yg_min_size);
|
|
||||||
|
|
||||||
og_min_size = align_size_up(og_min_size, og_align);
|
|
||||||
// Align old gen size down to preserve specified heap size.
|
|
||||||
assert(og_align == yg_align, "sanity");
|
|
||||||
og_max_size = align_size_down(og_max_size, og_align);
|
|
||||||
og_max_size = MAX2(og_max_size, og_min_size);
|
|
||||||
size_t og_cur_size =
|
|
||||||
align_size_down(_collector_policy->old_gen_size(), og_align);
|
|
||||||
og_cur_size = MAX2(og_cur_size, og_min_size);
|
|
||||||
|
|
||||||
trace_gen_sizes("ps heap rnd",
|
|
||||||
og_min_size, og_max_size,
|
|
||||||
yg_min_size, yg_max_size);
|
|
||||||
|
|
||||||
const size_t heap_size = og_max_size + yg_max_size;
|
|
||||||
|
|
||||||
ReservedSpace heap_rs = Universe::reserve_heap(heap_size, og_align);
|
|
||||||
|
|
||||||
|
ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
|
||||||
MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtJavaHeap);
|
MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtJavaHeap);
|
||||||
|
|
||||||
os::trace_page_sizes("ps main", og_min_size + yg_min_size,
|
os::trace_page_sizes("ps main", _collector_policy->min_heap_byte_size(),
|
||||||
og_max_size + yg_max_size, og_page_sz,
|
heap_size, generation_alignment(),
|
||||||
heap_rs.base(),
|
heap_rs.base(),
|
||||||
heap_rs.size());
|
heap_rs.size());
|
||||||
if (!heap_rs.is_reserved()) {
|
if (!heap_rs.is_reserved()) {
|
||||||
@ -142,12 +86,6 @@ jint ParallelScavengeHeap::initialize() {
|
|||||||
return JNI_ENOMEM;
|
return JNI_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial young gen size is 4 Mb
|
|
||||||
//
|
|
||||||
// XXX - what about flag_parser.young_gen_size()?
|
|
||||||
const size_t init_young_size = align_size_up(4 * M, yg_align);
|
|
||||||
yg_cur_size = MAX2(MIN2(init_young_size, yg_max_size), yg_cur_size);
|
|
||||||
|
|
||||||
// Make up the generations
|
// Make up the generations
|
||||||
// Calculate the maximum size that a generation can grow. This
|
// Calculate the maximum size that a generation can grow. This
|
||||||
// includes growth into the other generation. Note that the
|
// includes growth into the other generation. Note that the
|
||||||
@ -157,14 +95,7 @@ jint ParallelScavengeHeap::initialize() {
|
|||||||
double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
|
double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
|
||||||
double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
|
double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
|
||||||
|
|
||||||
_gens = new AdjoiningGenerations(heap_rs,
|
_gens = new AdjoiningGenerations(heap_rs, _collector_policy, generation_alignment());
|
||||||
og_cur_size,
|
|
||||||
og_min_size,
|
|
||||||
og_max_size,
|
|
||||||
yg_cur_size,
|
|
||||||
yg_min_size,
|
|
||||||
yg_max_size,
|
|
||||||
yg_align);
|
|
||||||
|
|
||||||
_old_gen = _gens->old_gen();
|
_old_gen = _gens->old_gen();
|
||||||
_young_gen = _gens->young_gen();
|
_young_gen = _gens->young_gen();
|
||||||
@ -176,7 +107,7 @@ jint ParallelScavengeHeap::initialize() {
|
|||||||
new PSAdaptiveSizePolicy(eden_capacity,
|
new PSAdaptiveSizePolicy(eden_capacity,
|
||||||
initial_promo_size,
|
initial_promo_size,
|
||||||
young_gen()->to_space()->capacity_in_bytes(),
|
young_gen()->to_space()->capacity_in_bytes(),
|
||||||
intra_heap_alignment(),
|
_collector_policy->gen_alignment(),
|
||||||
max_gc_pause_sec,
|
max_gc_pause_sec,
|
||||||
max_gc_minor_pause_sec,
|
max_gc_minor_pause_sec,
|
||||||
GCTimeRatio
|
GCTimeRatio
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARALLELSCAVENGEHEAP_HPP
|
#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARALLELSCAVENGEHEAP_HPP
|
||||||
#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARALLELSCAVENGEHEAP_HPP
|
#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARALLELSCAVENGEHEAP_HPP
|
||||||
|
|
||||||
|
#include "gc_implementation/parallelScavenge/generationSizer.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/objectStartArray.hpp"
|
#include "gc_implementation/parallelScavenge/objectStartArray.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
|
#include "gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp"
|
||||||
#include "gc_implementation/parallelScavenge/psOldGen.hpp"
|
#include "gc_implementation/parallelScavenge/psOldGen.hpp"
|
||||||
@ -32,13 +33,12 @@
|
|||||||
#include "gc_implementation/shared/gcPolicyCounters.hpp"
|
#include "gc_implementation/shared/gcPolicyCounters.hpp"
|
||||||
#include "gc_implementation/shared/gcWhen.hpp"
|
#include "gc_implementation/shared/gcWhen.hpp"
|
||||||
#include "gc_interface/collectedHeap.inline.hpp"
|
#include "gc_interface/collectedHeap.inline.hpp"
|
||||||
|
#include "memory/collectorPolicy.hpp"
|
||||||
#include "utilities/ostream.hpp"
|
#include "utilities/ostream.hpp"
|
||||||
|
|
||||||
class AdjoiningGenerations;
|
class AdjoiningGenerations;
|
||||||
class GCHeapSummary;
|
class GCHeapSummary;
|
||||||
class GCTaskManager;
|
class GCTaskManager;
|
||||||
class GenerationSizer;
|
|
||||||
class CollectorPolicy;
|
|
||||||
class PSAdaptiveSizePolicy;
|
class PSAdaptiveSizePolicy;
|
||||||
class PSHeapSummary;
|
class PSHeapSummary;
|
||||||
|
|
||||||
@ -54,13 +54,8 @@ class ParallelScavengeHeap : public CollectedHeap {
|
|||||||
|
|
||||||
static ParallelScavengeHeap* _psh;
|
static ParallelScavengeHeap* _psh;
|
||||||
|
|
||||||
size_t _young_gen_alignment;
|
|
||||||
size_t _old_gen_alignment;
|
|
||||||
|
|
||||||
GenerationSizer* _collector_policy;
|
GenerationSizer* _collector_policy;
|
||||||
|
|
||||||
inline size_t set_alignment(size_t& var, size_t val);
|
|
||||||
|
|
||||||
// Collection of generations that are adjacent in the
|
// Collection of generations that are adjacent in the
|
||||||
// space reserved for the heap.
|
// space reserved for the heap.
|
||||||
AdjoiningGenerations* _gens;
|
AdjoiningGenerations* _gens;
|
||||||
@ -80,15 +75,7 @@ class ParallelScavengeHeap : public CollectedHeap {
|
|||||||
HeapWord* mem_allocate_old_gen(size_t size);
|
HeapWord* mem_allocate_old_gen(size_t size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ParallelScavengeHeap() : CollectedHeap(), _death_march_count(0) {
|
ParallelScavengeHeap() : CollectedHeap(), _death_march_count(0) { }
|
||||||
set_alignment(_young_gen_alignment, intra_heap_alignment());
|
|
||||||
set_alignment(_old_gen_alignment, intra_heap_alignment());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the (conservative) maximum heap alignment
|
|
||||||
static size_t conservative_max_heap_alignment() {
|
|
||||||
return GenCollectorPolicy::intra_heap_alignment();
|
|
||||||
}
|
|
||||||
|
|
||||||
// For use by VM operations
|
// For use by VM operations
|
||||||
enum CollectionType {
|
enum CollectionType {
|
||||||
@ -120,13 +107,15 @@ class ParallelScavengeHeap : public CollectedHeap {
|
|||||||
|
|
||||||
void post_initialize();
|
void post_initialize();
|
||||||
void update_counters();
|
void update_counters();
|
||||||
// The alignment used for the various generations.
|
|
||||||
size_t young_gen_alignment() const { return _young_gen_alignment; }
|
|
||||||
size_t old_gen_alignment() const { return _old_gen_alignment; }
|
|
||||||
|
|
||||||
// The alignment used for eden and survivors within the young gen
|
// The alignment used for the various areas
|
||||||
// and for boundary between young gen and old gen.
|
size_t space_alignment() { return _collector_policy->space_alignment(); }
|
||||||
size_t intra_heap_alignment() { return GenCollectorPolicy::intra_heap_alignment(); }
|
size_t generation_alignment() { return _collector_policy->gen_alignment(); }
|
||||||
|
|
||||||
|
// Return the (conservative) maximum heap alignment
|
||||||
|
static size_t conservative_max_heap_alignment() {
|
||||||
|
return CollectorPolicy::compute_heap_alignment();
|
||||||
|
}
|
||||||
|
|
||||||
size_t capacity() const;
|
size_t capacity() const;
|
||||||
size_t used() const;
|
size_t used() const;
|
||||||
@ -261,11 +250,4 @@ class ParallelScavengeHeap : public CollectedHeap {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val)
|
|
||||||
{
|
|
||||||
assert(is_power_of_2((intptr_t)val), "must be a power of 2");
|
|
||||||
var = round_to(val, intra_heap_alignment());
|
|
||||||
return var;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARALLELSCAVENGEHEAP_HPP
|
#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PARALLELSCAVENGEHEAP_HPP
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
|
PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
|
||||||
size_t init_promo_size,
|
size_t init_promo_size,
|
||||||
size_t init_survivor_size,
|
size_t init_survivor_size,
|
||||||
size_t intra_generation_alignment,
|
size_t space_alignment,
|
||||||
double gc_pause_goal_sec,
|
double gc_pause_goal_sec,
|
||||||
double gc_minor_pause_goal_sec,
|
double gc_minor_pause_goal_sec,
|
||||||
uint gc_cost_ratio) :
|
uint gc_cost_ratio) :
|
||||||
@ -47,7 +47,7 @@ PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
|
|||||||
gc_pause_goal_sec,
|
gc_pause_goal_sec,
|
||||||
gc_cost_ratio),
|
gc_cost_ratio),
|
||||||
_collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin / 100.0),
|
_collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin / 100.0),
|
||||||
_intra_generation_alignment(intra_generation_alignment),
|
_space_alignment(space_alignment),
|
||||||
_live_at_last_full_gc(init_promo_size),
|
_live_at_last_full_gc(init_promo_size),
|
||||||
_gc_minor_pause_goal_sec(gc_minor_pause_goal_sec),
|
_gc_minor_pause_goal_sec(gc_minor_pause_goal_sec),
|
||||||
_latest_major_mutator_interval_seconds(0),
|
_latest_major_mutator_interval_seconds(0),
|
||||||
@ -352,11 +352,10 @@ void PSAdaptiveSizePolicy::compute_eden_space_size(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Align everything and make a final limit check
|
// Align everything and make a final limit check
|
||||||
const size_t alignment = _intra_generation_alignment;
|
desired_eden_size = align_size_up(desired_eden_size, _space_alignment);
|
||||||
desired_eden_size = align_size_up(desired_eden_size, alignment);
|
desired_eden_size = MAX2(desired_eden_size, _space_alignment);
|
||||||
desired_eden_size = MAX2(desired_eden_size, alignment);
|
|
||||||
|
|
||||||
eden_limit = align_size_down(eden_limit, alignment);
|
eden_limit = align_size_down(eden_limit, _space_alignment);
|
||||||
|
|
||||||
// And one last limit check, now that we've aligned things.
|
// And one last limit check, now that we've aligned things.
|
||||||
if (desired_eden_size > eden_limit) {
|
if (desired_eden_size > eden_limit) {
|
||||||
@ -560,11 +559,10 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Align everything and make a final limit check
|
// Align everything and make a final limit check
|
||||||
const size_t alignment = _intra_generation_alignment;
|
desired_promo_size = align_size_up(desired_promo_size, _space_alignment);
|
||||||
desired_promo_size = align_size_up(desired_promo_size, alignment);
|
desired_promo_size = MAX2(desired_promo_size, _space_alignment);
|
||||||
desired_promo_size = MAX2(desired_promo_size, alignment);
|
|
||||||
|
|
||||||
promo_limit = align_size_down(promo_limit, alignment);
|
promo_limit = align_size_down(promo_limit, _space_alignment);
|
||||||
|
|
||||||
// And one last limit check, now that we've aligned things.
|
// And one last limit check, now that we've aligned things.
|
||||||
desired_promo_size = MIN2(desired_promo_size, promo_limit);
|
desired_promo_size = MIN2(desired_promo_size, promo_limit);
|
||||||
@ -649,7 +647,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_minor_pause_time(bool is_full_gc,
|
|||||||
}
|
}
|
||||||
// If the desired eden size is as small as it will get,
|
// If the desired eden size is as small as it will get,
|
||||||
// try to adjust the old gen size.
|
// try to adjust the old gen size.
|
||||||
if (*desired_eden_size_ptr <= _intra_generation_alignment) {
|
if (*desired_eden_size_ptr <= _space_alignment) {
|
||||||
// Vary the old gen size to reduce the young gen pause. This
|
// Vary the old gen size to reduce the young gen pause. This
|
||||||
// may not be a good idea. This is just a test.
|
// may not be a good idea. This is just a test.
|
||||||
if (minor_pause_old_estimator()->decrement_will_decrease()) {
|
if (minor_pause_old_estimator()->decrement_will_decrease()) {
|
||||||
@ -754,7 +752,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
|
|||||||
// If the promo size is at the minimum (i.e., the old gen
|
// If the promo size is at the minimum (i.e., the old gen
|
||||||
// size will not actually decrease), consider changing the
|
// size will not actually decrease), consider changing the
|
||||||
// young gen size.
|
// young gen size.
|
||||||
if (*desired_promo_size_ptr < _intra_generation_alignment) {
|
if (*desired_promo_size_ptr < _space_alignment) {
|
||||||
// If increasing the young generation will decrease the old gen
|
// If increasing the young generation will decrease the old gen
|
||||||
// pause, do it.
|
// pause, do it.
|
||||||
// During startup there is noise in the statistics for deciding
|
// During startup there is noise in the statistics for deciding
|
||||||
@ -1065,24 +1063,24 @@ size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden) {
|
|||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::eden_increment_aligned_up(size_t cur_eden) {
|
size_t PSAdaptiveSizePolicy::eden_increment_aligned_up(size_t cur_eden) {
|
||||||
size_t result = eden_increment(cur_eden, YoungGenerationSizeIncrement);
|
size_t result = eden_increment(cur_eden, YoungGenerationSizeIncrement);
|
||||||
return align_size_up(result, _intra_generation_alignment);
|
return align_size_up(result, _space_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::eden_increment_aligned_down(size_t cur_eden) {
|
size_t PSAdaptiveSizePolicy::eden_increment_aligned_down(size_t cur_eden) {
|
||||||
size_t result = eden_increment(cur_eden);
|
size_t result = eden_increment(cur_eden);
|
||||||
return align_size_down(result, _intra_generation_alignment);
|
return align_size_down(result, _space_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::eden_increment_with_supplement_aligned_up(
|
size_t PSAdaptiveSizePolicy::eden_increment_with_supplement_aligned_up(
|
||||||
size_t cur_eden) {
|
size_t cur_eden) {
|
||||||
size_t result = eden_increment(cur_eden,
|
size_t result = eden_increment(cur_eden,
|
||||||
YoungGenerationSizeIncrement + _young_gen_size_increment_supplement);
|
YoungGenerationSizeIncrement + _young_gen_size_increment_supplement);
|
||||||
return align_size_up(result, _intra_generation_alignment);
|
return align_size_up(result, _space_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) {
|
size_t PSAdaptiveSizePolicy::eden_decrement_aligned_down(size_t cur_eden) {
|
||||||
size_t eden_heap_delta = eden_decrement(cur_eden);
|
size_t eden_heap_delta = eden_decrement(cur_eden);
|
||||||
return align_size_down(eden_heap_delta, _intra_generation_alignment);
|
return align_size_down(eden_heap_delta, _space_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::eden_decrement(size_t cur_eden) {
|
size_t PSAdaptiveSizePolicy::eden_decrement(size_t cur_eden) {
|
||||||
@ -1104,24 +1102,24 @@ size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo) {
|
|||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) {
|
size_t PSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) {
|
||||||
size_t result = promo_increment(cur_promo, TenuredGenerationSizeIncrement);
|
size_t result = promo_increment(cur_promo, TenuredGenerationSizeIncrement);
|
||||||
return align_size_up(result, _intra_generation_alignment);
|
return align_size_up(result, _space_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::promo_increment_aligned_down(size_t cur_promo) {
|
size_t PSAdaptiveSizePolicy::promo_increment_aligned_down(size_t cur_promo) {
|
||||||
size_t result = promo_increment(cur_promo, TenuredGenerationSizeIncrement);
|
size_t result = promo_increment(cur_promo, TenuredGenerationSizeIncrement);
|
||||||
return align_size_down(result, _intra_generation_alignment);
|
return align_size_down(result, _space_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::promo_increment_with_supplement_aligned_up(
|
size_t PSAdaptiveSizePolicy::promo_increment_with_supplement_aligned_up(
|
||||||
size_t cur_promo) {
|
size_t cur_promo) {
|
||||||
size_t result = promo_increment(cur_promo,
|
size_t result = promo_increment(cur_promo,
|
||||||
TenuredGenerationSizeIncrement + _old_gen_size_increment_supplement);
|
TenuredGenerationSizeIncrement + _old_gen_size_increment_supplement);
|
||||||
return align_size_up(result, _intra_generation_alignment);
|
return align_size_up(result, _space_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) {
|
size_t PSAdaptiveSizePolicy::promo_decrement_aligned_down(size_t cur_promo) {
|
||||||
size_t promo_heap_delta = promo_decrement(cur_promo);
|
size_t promo_heap_delta = promo_decrement(cur_promo);
|
||||||
return align_size_down(promo_heap_delta, _intra_generation_alignment);
|
return align_size_down(promo_heap_delta, _space_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PSAdaptiveSizePolicy::promo_decrement(size_t cur_promo) {
|
size_t PSAdaptiveSizePolicy::promo_decrement(size_t cur_promo) {
|
||||||
@ -1134,9 +1132,9 @@ uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
|
|||||||
bool is_survivor_overflow,
|
bool is_survivor_overflow,
|
||||||
uint tenuring_threshold,
|
uint tenuring_threshold,
|
||||||
size_t survivor_limit) {
|
size_t survivor_limit) {
|
||||||
assert(survivor_limit >= _intra_generation_alignment,
|
assert(survivor_limit >= _space_alignment,
|
||||||
"survivor_limit too small");
|
"survivor_limit too small");
|
||||||
assert((size_t)align_size_down(survivor_limit, _intra_generation_alignment)
|
assert((size_t)align_size_down(survivor_limit, _space_alignment)
|
||||||
== survivor_limit, "survivor_limit not aligned");
|
== survivor_limit, "survivor_limit not aligned");
|
||||||
|
|
||||||
// This method is called even if the tenuring threshold and survivor
|
// This method is called even if the tenuring threshold and survivor
|
||||||
@ -1200,8 +1198,8 @@ uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
|
|||||||
// We're trying to pad the survivor size as little as possible without
|
// We're trying to pad the survivor size as little as possible without
|
||||||
// overflowing the survivor spaces.
|
// overflowing the survivor spaces.
|
||||||
size_t target_size = align_size_up((size_t)_avg_survived->padded_average(),
|
size_t target_size = align_size_up((size_t)_avg_survived->padded_average(),
|
||||||
_intra_generation_alignment);
|
_space_alignment);
|
||||||
target_size = MAX2(target_size, _intra_generation_alignment);
|
target_size = MAX2(target_size, _space_alignment);
|
||||||
|
|
||||||
if (target_size > survivor_limit) {
|
if (target_size > survivor_limit) {
|
||||||
// Target size is bigger than we can handle. Let's also reduce
|
// Target size is bigger than we can handle. Let's also reduce
|
||||||
|
@ -91,7 +91,7 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
|||||||
// for making ergonomic decisions.
|
// for making ergonomic decisions.
|
||||||
double _latest_major_mutator_interval_seconds;
|
double _latest_major_mutator_interval_seconds;
|
||||||
|
|
||||||
const size_t _intra_generation_alignment; // alignment for eden, survivors
|
const size_t _space_alignment; // alignment for eden, survivors
|
||||||
|
|
||||||
const double _gc_minor_pause_goal_sec; // goal for maximum minor gc pause
|
const double _gc_minor_pause_goal_sec; // goal for maximum minor gc pause
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
|||||||
PSAdaptiveSizePolicy(size_t init_eden_size,
|
PSAdaptiveSizePolicy(size_t init_eden_size,
|
||||||
size_t init_promo_size,
|
size_t init_promo_size,
|
||||||
size_t init_survivor_size,
|
size_t init_survivor_size,
|
||||||
size_t intra_generation_alignment,
|
size_t space_alignment,
|
||||||
double gc_pause_goal_sec,
|
double gc_pause_goal_sec,
|
||||||
double gc_minor_pause_goal_sec,
|
double gc_minor_pause_goal_sec,
|
||||||
uint gc_time_ratio);
|
uint gc_time_ratio);
|
||||||
@ -378,7 +378,7 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
|
|||||||
// remain almost full anyway (top() will be near end(), but there will be a
|
// remain almost full anyway (top() will be near end(), but there will be a
|
||||||
// large filler object at the bottom).
|
// large filler object at the bottom).
|
||||||
const size_t sz = gen_size / MinSurvivorRatio;
|
const size_t sz = gen_size / MinSurvivorRatio;
|
||||||
const size_t alignment = _intra_generation_alignment;
|
const size_t alignment = _space_alignment;
|
||||||
return sz > alignment ? align_size_down(sz, alignment) : alignment;
|
return sz > alignment ? align_size_down(sz, alignment) : alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ void PSYoungGen::initialize_work() {
|
|||||||
|
|
||||||
// Compute maximum space sizes for performance counters
|
// Compute maximum space sizes for performance counters
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
size_t alignment = heap->intra_heap_alignment();
|
size_t alignment = heap->space_alignment();
|
||||||
size_t size = virtual_space()->reserved_size();
|
size_t size = virtual_space()->reserved_size();
|
||||||
|
|
||||||
size_t max_survivor_size;
|
size_t max_survivor_size;
|
||||||
@ -156,8 +156,9 @@ void PSYoungGen::compute_initial_space_boundaries() {
|
|||||||
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
|
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
|
||||||
|
|
||||||
// Compute sizes
|
// Compute sizes
|
||||||
size_t alignment = heap->intra_heap_alignment();
|
size_t alignment = heap->space_alignment();
|
||||||
size_t size = virtual_space()->committed_size();
|
size_t size = virtual_space()->committed_size();
|
||||||
|
assert(size >= 3 * alignment, "Young space is not large enough for eden + 2 survivors");
|
||||||
|
|
||||||
size_t survivor_size = size / InitialSurvivorRatio;
|
size_t survivor_size = size / InitialSurvivorRatio;
|
||||||
survivor_size = align_size_down(survivor_size, alignment);
|
survivor_size = align_size_down(survivor_size, alignment);
|
||||||
@ -207,7 +208,7 @@ void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) {
|
|||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
void PSYoungGen::space_invariants() {
|
void PSYoungGen::space_invariants() {
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
const size_t alignment = heap->intra_heap_alignment();
|
const size_t alignment = heap->space_alignment();
|
||||||
|
|
||||||
// Currently, our eden size cannot shrink to zero
|
// Currently, our eden size cannot shrink to zero
|
||||||
guarantee(eden_space()->capacity_in_bytes() >= alignment, "eden too small");
|
guarantee(eden_space()->capacity_in_bytes() >= alignment, "eden too small");
|
||||||
@ -491,7 +492,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size,
|
|||||||
char* to_end = (char*)to_space()->end();
|
char* to_end = (char*)to_space()->end();
|
||||||
|
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
const size_t alignment = heap->intra_heap_alignment();
|
const size_t alignment = heap->space_alignment();
|
||||||
const bool maintain_minimum =
|
const bool maintain_minimum =
|
||||||
(requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
|
(requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
|
||||||
|
|
||||||
@ -840,8 +841,8 @@ size_t PSYoungGen::available_to_min_gen() {
|
|||||||
size_t PSYoungGen::available_to_live() {
|
size_t PSYoungGen::available_to_live() {
|
||||||
size_t delta_in_survivor = 0;
|
size_t delta_in_survivor = 0;
|
||||||
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
|
||||||
const size_t space_alignment = heap->intra_heap_alignment();
|
const size_t space_alignment = heap->space_alignment();
|
||||||
const size_t gen_alignment = heap->young_gen_alignment();
|
const size_t gen_alignment = heap->generation_alignment();
|
||||||
|
|
||||||
MutableSpace* space_shrinking = NULL;
|
MutableSpace* space_shrinking = NULL;
|
||||||
if (from_space()->end() > to_space()->end()) {
|
if (from_space()->end() > to_space()->end()) {
|
||||||
|
@ -469,6 +469,10 @@ void CollectedHeap::fill_with_objects(HeapWord* start, size_t words, bool zap)
|
|||||||
fill_with_object_impl(start, words, zap);
|
fill_with_object_impl(start, words, zap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CollectedHeap::post_initialize() {
|
||||||
|
collector_policy()->post_heap_initialize();
|
||||||
|
}
|
||||||
|
|
||||||
HeapWord* CollectedHeap::allocate_new_tlab(size_t size) {
|
HeapWord* CollectedHeap::allocate_new_tlab(size_t size) {
|
||||||
guarantee(false, "thread-local allocation buffers not supported");
|
guarantee(false, "thread-local allocation buffers not supported");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -47,54 +47,107 @@
|
|||||||
|
|
||||||
// CollectorPolicy methods.
|
// CollectorPolicy methods.
|
||||||
|
|
||||||
void CollectorPolicy::initialize_flags() {
|
CollectorPolicy::CollectorPolicy() :
|
||||||
assert(_max_alignment >= _min_alignment,
|
_space_alignment(0),
|
||||||
err_msg("max_alignment: " SIZE_FORMAT " less than min_alignment: " SIZE_FORMAT,
|
_heap_alignment(0),
|
||||||
_max_alignment, _min_alignment));
|
_initial_heap_byte_size(InitialHeapSize),
|
||||||
assert(_max_alignment % _min_alignment == 0,
|
_max_heap_byte_size(MaxHeapSize),
|
||||||
err_msg("max_alignment: " SIZE_FORMAT " not aligned by min_alignment: " SIZE_FORMAT,
|
_min_heap_byte_size(Arguments::min_heap_size()),
|
||||||
_max_alignment, _min_alignment));
|
_max_heap_size_cmdline(false),
|
||||||
|
_size_policy(NULL),
|
||||||
|
_should_clear_all_soft_refs(false),
|
||||||
|
_all_soft_refs_clear(false)
|
||||||
|
{}
|
||||||
|
|
||||||
if (MaxHeapSize < InitialHeapSize) {
|
#ifdef ASSERT
|
||||||
vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
|
void CollectorPolicy::assert_flags() {
|
||||||
}
|
assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes");
|
||||||
|
assert(InitialHeapSize % _heap_alignment == 0, "InitialHeapSize alignment");
|
||||||
MinHeapDeltaBytes = align_size_up(MinHeapDeltaBytes, _min_alignment);
|
assert(MaxHeapSize % _heap_alignment == 0, "MaxHeapSize alignment");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectorPolicy::initialize_size_info() {
|
void CollectorPolicy::assert_size_info() {
|
||||||
// User inputs from -mx and ms must be aligned
|
assert(InitialHeapSize == _initial_heap_byte_size, "Discrepancy between InitialHeapSize flag and local storage");
|
||||||
_min_heap_byte_size = align_size_up(Arguments::min_heap_size(), _min_alignment);
|
assert(MaxHeapSize == _max_heap_byte_size, "Discrepancy between MaxHeapSize flag and local storage");
|
||||||
_initial_heap_byte_size = align_size_up(InitialHeapSize, _min_alignment);
|
assert(_max_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible minimum and maximum heap sizes");
|
||||||
_max_heap_byte_size = align_size_up(MaxHeapSize, _max_alignment);
|
assert(_initial_heap_byte_size >= _min_heap_byte_size, "Ergonomics decided on incompatible initial and minimum heap sizes");
|
||||||
|
assert(_max_heap_byte_size >= _initial_heap_byte_size, "Ergonomics decided on incompatible initial and maximum heap sizes");
|
||||||
|
assert(_min_heap_byte_size % _heap_alignment == 0, "min_heap_byte_size alignment");
|
||||||
|
assert(_initial_heap_byte_size % _heap_alignment == 0, "initial_heap_byte_size alignment");
|
||||||
|
assert(_max_heap_byte_size % _heap_alignment == 0, "max_heap_byte_size alignment");
|
||||||
|
}
|
||||||
|
#endif // ASSERT
|
||||||
|
|
||||||
|
void CollectorPolicy::initialize_flags() {
|
||||||
|
assert(_space_alignment != 0, "Space alignment not set up properly");
|
||||||
|
assert(_heap_alignment != 0, "Heap alignment not set up properly");
|
||||||
|
assert(_heap_alignment >= _space_alignment,
|
||||||
|
err_msg("heap_alignment: " SIZE_FORMAT " less than space_alignment: " SIZE_FORMAT,
|
||||||
|
_heap_alignment, _space_alignment));
|
||||||
|
assert(_heap_alignment % _space_alignment == 0,
|
||||||
|
err_msg("heap_alignment: " SIZE_FORMAT " not aligned by space_alignment: " SIZE_FORMAT,
|
||||||
|
_heap_alignment, _space_alignment));
|
||||||
|
|
||||||
|
if (FLAG_IS_CMDLINE(MaxHeapSize)) {
|
||||||
|
if (FLAG_IS_CMDLINE(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
|
||||||
|
vm_exit_during_initialization("Initial heap size set to a larger value than the maximum heap size");
|
||||||
|
}
|
||||||
|
if (_min_heap_byte_size != 0 && MaxHeapSize < _min_heap_byte_size) {
|
||||||
|
vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
|
||||||
|
}
|
||||||
|
_max_heap_size_cmdline = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Check heap parameter properties
|
// Check heap parameter properties
|
||||||
if (_initial_heap_byte_size < M) {
|
if (InitialHeapSize < M) {
|
||||||
vm_exit_during_initialization("Too small initial heap");
|
vm_exit_during_initialization("Too small initial heap");
|
||||||
}
|
}
|
||||||
// Check heap parameter properties
|
|
||||||
if (_min_heap_byte_size < M) {
|
if (_min_heap_byte_size < M) {
|
||||||
vm_exit_during_initialization("Too small minimum heap");
|
vm_exit_during_initialization("Too small minimum heap");
|
||||||
}
|
}
|
||||||
if (_initial_heap_byte_size <= NewSize) {
|
|
||||||
// make sure there is at least some room in old space
|
// User inputs from -Xmx and -Xms must be aligned
|
||||||
vm_exit_during_initialization("Too small initial heap for new size specified");
|
_min_heap_byte_size = align_size_up(_min_heap_byte_size, _heap_alignment);
|
||||||
|
uintx aligned_initial_heap_size = align_size_up(InitialHeapSize, _heap_alignment);
|
||||||
|
uintx aligned_max_heap_size = align_size_up(MaxHeapSize, _heap_alignment);
|
||||||
|
|
||||||
|
// Write back to flags if the values changed
|
||||||
|
if (aligned_initial_heap_size != InitialHeapSize) {
|
||||||
|
FLAG_SET_ERGO(uintx, InitialHeapSize, aligned_initial_heap_size);
|
||||||
}
|
}
|
||||||
if (_max_heap_byte_size < _min_heap_byte_size) {
|
if (aligned_max_heap_size != MaxHeapSize) {
|
||||||
vm_exit_during_initialization("Incompatible minimum and maximum heap sizes specified");
|
FLAG_SET_ERGO(uintx, MaxHeapSize, aligned_max_heap_size);
|
||||||
}
|
|
||||||
if (_initial_heap_byte_size < _min_heap_byte_size) {
|
|
||||||
vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
|
|
||||||
}
|
|
||||||
if (_max_heap_byte_size < _initial_heap_byte_size) {
|
|
||||||
vm_exit_during_initialization("Incompatible initial and maximum heap sizes specified");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FLAG_IS_CMDLINE(InitialHeapSize) && _min_heap_byte_size != 0 &&
|
||||||
|
InitialHeapSize < _min_heap_byte_size) {
|
||||||
|
vm_exit_during_initialization("Incompatible minimum and initial heap sizes specified");
|
||||||
|
}
|
||||||
|
if (!FLAG_IS_DEFAULT(InitialHeapSize) && InitialHeapSize > MaxHeapSize) {
|
||||||
|
FLAG_SET_ERGO(uintx, MaxHeapSize, InitialHeapSize);
|
||||||
|
} else if (!FLAG_IS_DEFAULT(MaxHeapSize) && InitialHeapSize > MaxHeapSize) {
|
||||||
|
FLAG_SET_ERGO(uintx, InitialHeapSize, MaxHeapSize);
|
||||||
|
if (InitialHeapSize < _min_heap_byte_size) {
|
||||||
|
_min_heap_byte_size = InitialHeapSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_initial_heap_byte_size = InitialHeapSize;
|
||||||
|
_max_heap_byte_size = MaxHeapSize;
|
||||||
|
|
||||||
|
FLAG_SET_ERGO(uintx, MinHeapDeltaBytes, align_size_up(MinHeapDeltaBytes, _space_alignment));
|
||||||
|
|
||||||
|
DEBUG_ONLY(CollectorPolicy::assert_flags();)
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectorPolicy::initialize_size_info() {
|
||||||
if (PrintGCDetails && Verbose) {
|
if (PrintGCDetails && Verbose) {
|
||||||
gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
|
gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
|
||||||
SIZE_FORMAT " Maximum heap " SIZE_FORMAT,
|
SIZE_FORMAT " Maximum heap " SIZE_FORMAT,
|
||||||
_min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
|
_min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_ONLY(CollectorPolicy::assert_size_info();)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
|
bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
|
||||||
@ -118,7 +171,7 @@ void CollectorPolicy::cleared_all_soft_refs() {
|
|||||||
_all_soft_refs_clear = true;
|
_all_soft_refs_clear = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CollectorPolicy::compute_max_alignment() {
|
size_t CollectorPolicy::compute_heap_alignment() {
|
||||||
// The card marking array and the offset arrays for old generations are
|
// The card marking array and the offset arrays for old generations are
|
||||||
// committed in os pages as well. Make sure they are entirely full (to
|
// committed in os pages as well. Make sure they are entirely full (to
|
||||||
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
|
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
|
||||||
@ -145,14 +198,21 @@ size_t CollectorPolicy::compute_max_alignment() {
|
|||||||
|
|
||||||
// GenCollectorPolicy methods.
|
// GenCollectorPolicy methods.
|
||||||
|
|
||||||
|
GenCollectorPolicy::GenCollectorPolicy() :
|
||||||
|
_min_gen0_size(0),
|
||||||
|
_initial_gen0_size(0),
|
||||||
|
_max_gen0_size(0),
|
||||||
|
_gen_alignment(0),
|
||||||
|
_generations(NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
|
size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
|
||||||
return align_size_down_bounded(base_size / (NewRatio + 1), _min_alignment);
|
return align_size_down_bounded(base_size / (NewRatio + 1), _gen_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
|
size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
|
||||||
size_t maximum_size) {
|
size_t maximum_size) {
|
||||||
size_t alignment = _min_alignment;
|
size_t max_minus = maximum_size - _gen_alignment;
|
||||||
size_t max_minus = maximum_size - alignment;
|
|
||||||
return desired_size < max_minus ? desired_size : max_minus;
|
return desired_size < max_minus ? desired_size : max_minus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,101 +228,181 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
|
|||||||
GCTimeRatio);
|
GCTimeRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenCollectorPolicy::initialize_flags() {
|
size_t GenCollectorPolicy::young_gen_size_lower_bound() {
|
||||||
// All sizes must be multiples of the generation granularity.
|
// The young generation must be aligned and have room for eden + two survivors
|
||||||
_min_alignment = (uintx) Generation::GenGrain;
|
return align_size_up(3 * _space_alignment, _gen_alignment);
|
||||||
_max_alignment = compute_max_alignment();
|
}
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
void GenCollectorPolicy::assert_flags() {
|
||||||
|
CollectorPolicy::assert_flags();
|
||||||
|
assert(NewSize >= _min_gen0_size, "Ergonomics decided on a too small young gen size");
|
||||||
|
assert(NewSize <= MaxNewSize, "Ergonomics decided on incompatible initial and maximum young gen sizes");
|
||||||
|
assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young gen and heap sizes");
|
||||||
|
assert(NewSize % _gen_alignment == 0, "NewSize alignment");
|
||||||
|
assert(FLAG_IS_DEFAULT(MaxNewSize) || MaxNewSize % _gen_alignment == 0, "MaxNewSize alignment");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoGenerationCollectorPolicy::assert_flags() {
|
||||||
|
GenCollectorPolicy::assert_flags();
|
||||||
|
assert(OldSize + NewSize <= MaxHeapSize, "Ergonomics decided on incompatible generation and heap sizes");
|
||||||
|
assert(OldSize % _gen_alignment == 0, "OldSize alignment");
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenCollectorPolicy::assert_size_info() {
|
||||||
|
CollectorPolicy::assert_size_info();
|
||||||
|
// GenCollectorPolicy::initialize_size_info may update the MaxNewSize
|
||||||
|
assert(MaxNewSize < MaxHeapSize, "Ergonomics decided on incompatible maximum young and heap sizes");
|
||||||
|
assert(NewSize == _initial_gen0_size, "Discrepancy between NewSize flag and local storage");
|
||||||
|
assert(MaxNewSize == _max_gen0_size, "Discrepancy between MaxNewSize flag and local storage");
|
||||||
|
assert(_min_gen0_size <= _initial_gen0_size, "Ergonomics decided on incompatible minimum and initial young gen sizes");
|
||||||
|
assert(_initial_gen0_size <= _max_gen0_size, "Ergonomics decided on incompatible initial and maximum young gen sizes");
|
||||||
|
assert(_min_gen0_size % _gen_alignment == 0, "_min_gen0_size alignment");
|
||||||
|
assert(_initial_gen0_size % _gen_alignment == 0, "_initial_gen0_size alignment");
|
||||||
|
assert(_max_gen0_size % _gen_alignment == 0, "_max_gen0_size alignment");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoGenerationCollectorPolicy::assert_size_info() {
|
||||||
|
GenCollectorPolicy::assert_size_info();
|
||||||
|
assert(OldSize == _initial_gen1_size, "Discrepancy between OldSize flag and local storage");
|
||||||
|
assert(_min_gen1_size <= _initial_gen1_size, "Ergonomics decided on incompatible minimum and initial old gen sizes");
|
||||||
|
assert(_initial_gen1_size <= _max_gen1_size, "Ergonomics decided on incompatible initial and maximum old gen sizes");
|
||||||
|
assert(_max_gen1_size % _gen_alignment == 0, "_max_gen1_size alignment");
|
||||||
|
assert(_initial_gen1_size % _gen_alignment == 0, "_initial_gen1_size alignment");
|
||||||
|
assert(_max_heap_byte_size <= (_max_gen0_size + _max_gen1_size), "Total maximum heap sizes must be sum of generation maximum sizes");
|
||||||
|
}
|
||||||
|
#endif // ASSERT
|
||||||
|
|
||||||
|
void GenCollectorPolicy::initialize_flags() {
|
||||||
CollectorPolicy::initialize_flags();
|
CollectorPolicy::initialize_flags();
|
||||||
|
|
||||||
// All generational heaps have a youngest gen; handle those flags here.
|
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));
|
||||||
|
|
||||||
// Adjust max size parameters
|
// All generational heaps have a youngest gen; handle those flags here
|
||||||
if (NewSize > MaxNewSize) {
|
|
||||||
MaxNewSize = NewSize;
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NewSize = align_size_down(NewSize, _min_alignment);
|
|
||||||
MaxNewSize = align_size_down(MaxNewSize, _min_alignment);
|
|
||||||
|
|
||||||
// Check validity of heap flags
|
// Now take the actual NewSize into account. We will silently increase NewSize
|
||||||
assert(NewSize % _min_alignment == 0, "eden space alignment");
|
// if the user specified a smaller value.
|
||||||
assert(MaxNewSize % _min_alignment == 0, "survivor space alignment");
|
smallest_new_size = MAX2(smallest_new_size, (uintx)align_size_down(NewSize, _gen_alignment));
|
||||||
|
if (smallest_new_size != NewSize) {
|
||||||
|
FLAG_SET_ERGO(uintx, NewSize, smallest_new_size);
|
||||||
|
}
|
||||||
|
_initial_gen0_size = NewSize;
|
||||||
|
|
||||||
if (NewSize < 3 * _min_alignment) {
|
if (!FLAG_IS_DEFAULT(MaxNewSize)) {
|
||||||
// make sure there room for eden and two survivor spaces
|
uintx min_new_size = MAX2(_gen_alignment, _min_gen0_size);
|
||||||
vm_exit_during_initialization("Too small new size specified");
|
|
||||||
|
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) {
|
if (SurvivorRatio < 1 || NewRatio < 1) {
|
||||||
vm_exit_during_initialization("Invalid young gen ratio specified");
|
vm_exit_during_initialization("Invalid young gen ratio specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_ONLY(GenCollectorPolicy::assert_flags();)
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoGenerationCollectorPolicy::initialize_flags() {
|
void TwoGenerationCollectorPolicy::initialize_flags() {
|
||||||
GenCollectorPolicy::initialize_flags();
|
GenCollectorPolicy::initialize_flags();
|
||||||
|
|
||||||
OldSize = align_size_down(OldSize, _min_alignment);
|
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(NewSize)) {
|
if (FLAG_IS_CMDLINE(OldSize) && FLAG_IS_DEFAULT(MaxHeapSize)) {
|
||||||
// NewRatio will be used later to set the young generation size so we use
|
// 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
|
// it to calculate how big the heap should be based on the requested OldSize
|
||||||
// and NewRatio.
|
// and NewRatio.
|
||||||
assert(NewRatio > 0, "NewRatio should have been set up earlier");
|
assert(NewRatio > 0, "NewRatio should have been set up earlier");
|
||||||
size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
|
size_t calculated_heapsize = (OldSize / NewRatio) * (NewRatio + 1);
|
||||||
|
|
||||||
calculated_heapsize = align_size_up(calculated_heapsize, _max_alignment);
|
calculated_heapsize = align_size_up(calculated_heapsize, _heap_alignment);
|
||||||
MaxHeapSize = calculated_heapsize;
|
FLAG_SET_ERGO(uintx, MaxHeapSize, calculated_heapsize);
|
||||||
InitialHeapSize = calculated_heapsize;
|
_max_heap_byte_size = MaxHeapSize;
|
||||||
|
FLAG_SET_ERGO(uintx, InitialHeapSize, calculated_heapsize);
|
||||||
|
_initial_heap_byte_size = InitialHeapSize;
|
||||||
}
|
}
|
||||||
MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment);
|
|
||||||
|
|
||||||
// adjust max heap size if necessary
|
// adjust max heap size if necessary
|
||||||
if (NewSize + OldSize > MaxHeapSize) {
|
if (NewSize + OldSize > MaxHeapSize) {
|
||||||
if (FLAG_IS_CMDLINE(MaxHeapSize)) {
|
if (_max_heap_size_cmdline) {
|
||||||
// somebody set a maximum heap size with the intention that we should not
|
// somebody set a maximum heap size with the intention that we should not
|
||||||
// exceed it. Adjust New/OldSize as necessary.
|
// exceed it. Adjust New/OldSize as necessary.
|
||||||
uintx calculated_size = NewSize + OldSize;
|
uintx calculated_size = NewSize + OldSize;
|
||||||
double shrink_factor = (double) MaxHeapSize / calculated_size;
|
double shrink_factor = (double) MaxHeapSize / calculated_size;
|
||||||
// align
|
uintx smaller_new_size = align_size_down((uintx)(NewSize * shrink_factor), _gen_alignment);
|
||||||
NewSize = align_size_down((uintx) (NewSize * shrink_factor), _min_alignment);
|
FLAG_SET_ERGO(uintx, NewSize, MAX2(young_gen_size_lower_bound(), smaller_new_size));
|
||||||
// OldSize is already aligned because above we aligned MaxHeapSize to
|
_initial_gen0_size = NewSize;
|
||||||
// _max_alignment, and we just made sure that NewSize is aligned to
|
|
||||||
// _min_alignment. In initialize_flags() we verified that _max_alignment
|
|
||||||
// is a multiple of _min_alignment.
|
|
||||||
OldSize = MaxHeapSize - NewSize;
|
|
||||||
} else {
|
|
||||||
MaxHeapSize = NewSize + OldSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// need to do this again
|
|
||||||
MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment);
|
|
||||||
|
|
||||||
// adjust max heap size if necessary
|
|
||||||
if (NewSize + OldSize > MaxHeapSize) {
|
|
||||||
if (FLAG_IS_CMDLINE(MaxHeapSize)) {
|
|
||||||
// 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;
|
|
||||||
// align
|
|
||||||
NewSize = align_size_down((uintx) (NewSize * shrink_factor), _min_alignment);
|
|
||||||
// OldSize is already aligned because above we aligned MaxHeapSize to
|
// OldSize is already aligned because above we aligned MaxHeapSize to
|
||||||
// _max_alignment, and we just made sure that NewSize is aligned to
|
// _heap_alignment, and we just made sure that NewSize is aligned to
|
||||||
// _min_alignment. In initialize_flags() we verified that _max_alignment
|
// _gen_alignment. In initialize_flags() we verified that _heap_alignment
|
||||||
// is a multiple of _min_alignment.
|
// is a multiple of _gen_alignment.
|
||||||
OldSize = MaxHeapSize - NewSize;
|
FLAG_SET_ERGO(uintx, OldSize, MaxHeapSize - NewSize);
|
||||||
} else {
|
} else {
|
||||||
MaxHeapSize = NewSize + OldSize;
|
FLAG_SET_ERGO(uintx, MaxHeapSize, align_size_up(NewSize + OldSize, _heap_alignment));
|
||||||
|
_max_heap_byte_size = MaxHeapSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// need to do this again
|
|
||||||
MaxHeapSize = align_size_up(MaxHeapSize, _max_alignment);
|
|
||||||
|
|
||||||
always_do_update_barrier = UseConcMarkSweepGC;
|
always_do_update_barrier = UseConcMarkSweepGC;
|
||||||
|
|
||||||
// Check validity of heap flags
|
DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_flags();)
|
||||||
assert(OldSize % _min_alignment == 0, "old space alignment");
|
|
||||||
assert(MaxHeapSize % _max_alignment == 0, "maximum heap alignment");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values set on the command line win over any ergonomically
|
// Values set on the command line win over any ergonomically
|
||||||
@ -277,7 +417,7 @@ void TwoGenerationCollectorPolicy::initialize_flags() {
|
|||||||
void GenCollectorPolicy::initialize_size_info() {
|
void GenCollectorPolicy::initialize_size_info() {
|
||||||
CollectorPolicy::initialize_size_info();
|
CollectorPolicy::initialize_size_info();
|
||||||
|
|
||||||
// _min_alignment is used for alignment within a generation.
|
// _space_alignment is used for alignment within a generation.
|
||||||
// There is additional alignment done down stream for some
|
// There is additional alignment done down stream for some
|
||||||
// collectors that sometimes causes unwanted rounding up of
|
// collectors that sometimes causes unwanted rounding up of
|
||||||
// generations sizes.
|
// generations sizes.
|
||||||
@ -285,35 +425,8 @@ void GenCollectorPolicy::initialize_size_info() {
|
|||||||
// Determine maximum size of gen0
|
// Determine maximum size of gen0
|
||||||
|
|
||||||
size_t max_new_size = 0;
|
size_t max_new_size = 0;
|
||||||
if (FLAG_IS_CMDLINE(MaxNewSize) || FLAG_IS_ERGO(MaxNewSize)) {
|
if (!FLAG_IS_DEFAULT(MaxNewSize)) {
|
||||||
if (MaxNewSize < _min_alignment) {
|
max_new_size = MaxNewSize;
|
||||||
max_new_size = _min_alignment;
|
|
||||||
}
|
|
||||||
if (MaxNewSize >= _max_heap_byte_size) {
|
|
||||||
max_new_size = align_size_down(_max_heap_byte_size - _min_alignment,
|
|
||||||
_min_alignment);
|
|
||||||
warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or "
|
|
||||||
"greater than the entire heap (" SIZE_FORMAT "k). A "
|
|
||||||
"new generation size of " SIZE_FORMAT "k will be used.",
|
|
||||||
MaxNewSize/K, _max_heap_byte_size/K, max_new_size/K);
|
|
||||||
} else {
|
|
||||||
max_new_size = align_size_down(MaxNewSize, _min_alignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The case for FLAG_IS_ERGO(MaxNewSize) could be treated
|
|
||||||
// specially at this point to just use an ergonomically set
|
|
||||||
// MaxNewSize to set max_new_size. For cases with small
|
|
||||||
// heaps such a policy often did not work because the MaxNewSize
|
|
||||||
// was larger than the entire heap. The interpretation given
|
|
||||||
// to ergonomically set flags is that the flags are set
|
|
||||||
// by different collectors for their own special needs but
|
|
||||||
// are not allowed to badly shape the heap. This allows the
|
|
||||||
// different collectors to decide what's best for themselves
|
|
||||||
// without having to factor in the overall heap shape. It
|
|
||||||
// can be the case in the future that the collectors would
|
|
||||||
// only make "wise" ergonomics choices and this policy could
|
|
||||||
// just accept those choices. The choices currently made are
|
|
||||||
// not always "wise".
|
|
||||||
} else {
|
} else {
|
||||||
max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size);
|
max_new_size = scale_by_NewRatio_aligned(_max_heap_byte_size);
|
||||||
// Bound the maximum size by NewSize below (since it historically
|
// Bound the maximum size by NewSize below (since it historically
|
||||||
@ -382,11 +495,22 @@ void GenCollectorPolicy::initialize_size_info() {
|
|||||||
_min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size);
|
_min_gen0_size = MIN2(_min_gen0_size, _initial_gen0_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write back to flags if necessary
|
||||||
|
if (NewSize != _initial_gen0_size) {
|
||||||
|
FLAG_SET_ERGO(uintx, NewSize, _initial_gen0_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MaxNewSize != _max_gen0_size) {
|
||||||
|
FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (PrintGCDetails && Verbose) {
|
if (PrintGCDetails && Verbose) {
|
||||||
gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
|
gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
|
||||||
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
|
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
|
||||||
_min_gen0_size, _initial_gen0_size, _max_gen0_size);
|
_min_gen0_size, _initial_gen0_size, _max_gen0_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this method during the sizing of the gen1 to make
|
// Call this method during the sizing of the gen1 to make
|
||||||
@ -404,14 +528,15 @@ bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr,
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) {
|
if ((*gen1_size_ptr + *gen0_size_ptr) > heap_size) {
|
||||||
|
uintx smallest_new_size = young_gen_size_lower_bound();
|
||||||
if ((heap_size < (*gen0_size_ptr + min_gen1_size)) &&
|
if ((heap_size < (*gen0_size_ptr + min_gen1_size)) &&
|
||||||
(heap_size >= min_gen1_size + _min_alignment)) {
|
(heap_size >= min_gen1_size + smallest_new_size)) {
|
||||||
// Adjust gen0 down to accommodate min_gen1_size
|
// Adjust gen0 down to accommodate min_gen1_size
|
||||||
*gen0_size_ptr = align_size_down_bounded(heap_size - min_gen1_size, _min_alignment);
|
*gen0_size_ptr = align_size_down_bounded(heap_size - min_gen1_size, _gen_alignment);
|
||||||
assert(*gen0_size_ptr > 0, "Min gen0 is too large");
|
assert(*gen0_size_ptr > 0, "Min gen0 is too large");
|
||||||
result = true;
|
result = true;
|
||||||
} else {
|
} else {
|
||||||
*gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _min_alignment);
|
*gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _gen_alignment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -432,36 +557,31 @@ void TwoGenerationCollectorPolicy::initialize_size_info() {
|
|||||||
// The maximum gen1 size can be determined from the maximum gen0
|
// The maximum gen1 size can be determined from the maximum gen0
|
||||||
// and maximum heap size since no explicit flags exits
|
// and maximum heap size since no explicit flags exits
|
||||||
// for setting the gen1 maximum.
|
// for setting the gen1 maximum.
|
||||||
_max_gen1_size = _max_heap_byte_size - _max_gen0_size;
|
_max_gen1_size = MAX2(_max_heap_byte_size - _max_gen0_size, _gen_alignment);
|
||||||
_max_gen1_size =
|
|
||||||
MAX2((uintx)align_size_down(_max_gen1_size, _min_alignment), _min_alignment);
|
|
||||||
// If no explicit command line flag has been set for the
|
// If no explicit command line flag has been set for the
|
||||||
// gen1 size, use what is left for gen1.
|
// gen1 size, use what is left for gen1.
|
||||||
if (FLAG_IS_DEFAULT(OldSize) || FLAG_IS_ERGO(OldSize)) {
|
if (!FLAG_IS_CMDLINE(OldSize)) {
|
||||||
// The user has not specified any value or ergonomics
|
// The user has not specified any value but the ergonomics
|
||||||
// has chosen a value (which may or may not be consistent
|
// may have chosen a value (which may or may not be consistent
|
||||||
// with the overall heap size). In either case make
|
// with the overall heap size). In either case make
|
||||||
// the minimum, maximum and initial sizes consistent
|
// the minimum, maximum and initial sizes consistent
|
||||||
// with the gen0 sizes and the overall heap sizes.
|
// with the gen0 sizes and the overall heap sizes.
|
||||||
assert(_min_heap_byte_size > _min_gen0_size,
|
_min_gen1_size = MAX2(_min_heap_byte_size - _min_gen0_size, _gen_alignment);
|
||||||
"gen0 has an unexpected minimum size");
|
_initial_gen1_size = MAX2(_initial_heap_byte_size - _initial_gen0_size, _gen_alignment);
|
||||||
_min_gen1_size = _min_heap_byte_size - _min_gen0_size;
|
// _max_gen1_size has already been made consistent above
|
||||||
_min_gen1_size =
|
FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);
|
||||||
MAX2((uintx)align_size_down(_min_gen1_size, _min_alignment), _min_alignment);
|
|
||||||
_initial_gen1_size = _initial_heap_byte_size - _initial_gen0_size;
|
|
||||||
_initial_gen1_size =
|
|
||||||
MAX2((uintx)align_size_down(_initial_gen1_size, _min_alignment), _min_alignment);
|
|
||||||
} else {
|
} else {
|
||||||
// It's been explicitly set on the command line. Use the
|
// It's been explicitly set on the command line. Use the
|
||||||
// OldSize and then determine the consequences.
|
// OldSize and then determine the consequences.
|
||||||
_min_gen1_size = OldSize;
|
_min_gen1_size = MIN2(OldSize, _min_heap_byte_size - _min_gen0_size);
|
||||||
_initial_gen1_size = OldSize;
|
_initial_gen1_size = OldSize;
|
||||||
|
|
||||||
// If the user has explicitly set an OldSize that is inconsistent
|
// If the user has explicitly set an OldSize that is inconsistent
|
||||||
// with other command line flags, issue a warning.
|
// with other command line flags, issue a warning.
|
||||||
// The generation minimums and the overall heap mimimum should
|
// The generation minimums and the overall heap mimimum should
|
||||||
// be within one heap alignment.
|
// be within one generation alignment.
|
||||||
if ((_min_gen1_size + _min_gen0_size + _min_alignment) < _min_heap_byte_size) {
|
if ((_min_gen1_size + _min_gen0_size + _gen_alignment) < _min_heap_byte_size) {
|
||||||
warning("Inconsistency between minimum heap size and minimum "
|
warning("Inconsistency between minimum heap size and minimum "
|
||||||
"generation sizes: using minimum heap = " SIZE_FORMAT,
|
"generation sizes: using minimum heap = " SIZE_FORMAT,
|
||||||
_min_heap_byte_size);
|
_min_heap_byte_size);
|
||||||
@ -475,7 +595,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() {
|
|||||||
// If there is an inconsistency between the OldSize and the minimum and/or
|
// If there is an inconsistency between the OldSize and the minimum and/or
|
||||||
// initial size of gen0, since OldSize was explicitly set, OldSize wins.
|
// initial size of gen0, since OldSize was explicitly set, OldSize wins.
|
||||||
if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
|
if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
|
||||||
_min_heap_byte_size, OldSize)) {
|
_min_heap_byte_size, _min_gen1_size)) {
|
||||||
if (PrintGCDetails && Verbose) {
|
if (PrintGCDetails && Verbose) {
|
||||||
gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
|
gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
|
||||||
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
|
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
|
||||||
@ -484,7 +604,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() {
|
|||||||
}
|
}
|
||||||
// Initial size
|
// Initial size
|
||||||
if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
|
if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
|
||||||
_initial_heap_byte_size, OldSize)) {
|
_initial_heap_byte_size, _initial_gen1_size)) {
|
||||||
if (PrintGCDetails && Verbose) {
|
if (PrintGCDetails && Verbose) {
|
||||||
gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
|
gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT " Initial gen0 "
|
||||||
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
|
SIZE_FORMAT " Maximum gen0 " SIZE_FORMAT,
|
||||||
@ -499,11 +619,26 @@ void TwoGenerationCollectorPolicy::initialize_size_info() {
|
|||||||
_initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size);
|
_initial_gen1_size = MAX2(_initial_gen1_size, _min_gen1_size);
|
||||||
_initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size);
|
_initial_gen1_size = MIN2(_initial_gen1_size, _max_gen1_size);
|
||||||
|
|
||||||
|
// Write back to flags if necessary
|
||||||
|
if (NewSize != _initial_gen0_size) {
|
||||||
|
FLAG_SET_ERGO(uintx, NewSize, _max_gen0_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MaxNewSize != _max_gen0_size) {
|
||||||
|
FLAG_SET_ERGO(uintx, MaxNewSize, _max_gen0_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OldSize != _initial_gen1_size) {
|
||||||
|
FLAG_SET_ERGO(uintx, OldSize, _initial_gen1_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (PrintGCDetails && Verbose) {
|
if (PrintGCDetails && Verbose) {
|
||||||
gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 "
|
gclog_or_tty->print_cr("Minimum gen1 " SIZE_FORMAT " Initial gen1 "
|
||||||
SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT,
|
SIZE_FORMAT " Maximum gen1 " SIZE_FORMAT,
|
||||||
_min_gen1_size, _initial_gen1_size, _max_gen1_size);
|
_min_gen1_size, _initial_gen1_size, _max_gen1_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_ONLY(TwoGenerationCollectorPolicy::assert_size_info();)
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
|
HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
|
||||||
@ -826,8 +961,9 @@ bool GenCollectorPolicy::should_try_older_generation_allocation(
|
|||||||
// MarkSweepPolicy methods
|
// MarkSweepPolicy methods
|
||||||
//
|
//
|
||||||
|
|
||||||
MarkSweepPolicy::MarkSweepPolicy() {
|
void MarkSweepPolicy::initialize_alignments() {
|
||||||
initialize_all();
|
_space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
|
||||||
|
_heap_alignment = compute_heap_alignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkSweepPolicy::initialize_generations() {
|
void MarkSweepPolicy::initialize_generations() {
|
||||||
|
@ -61,17 +61,23 @@ class CollectorPolicy : public CHeapObj<mtGC> {
|
|||||||
protected:
|
protected:
|
||||||
GCPolicyCounters* _gc_policy_counters;
|
GCPolicyCounters* _gc_policy_counters;
|
||||||
|
|
||||||
// Requires that the concrete subclass sets the alignment constraints
|
virtual void initialize_alignments() = 0;
|
||||||
// before calling.
|
|
||||||
virtual void initialize_flags();
|
virtual void initialize_flags();
|
||||||
virtual void initialize_size_info();
|
virtual void initialize_size_info();
|
||||||
|
|
||||||
|
DEBUG_ONLY(virtual void assert_flags();)
|
||||||
|
DEBUG_ONLY(virtual void assert_size_info();)
|
||||||
|
|
||||||
size_t _initial_heap_byte_size;
|
size_t _initial_heap_byte_size;
|
||||||
size_t _max_heap_byte_size;
|
size_t _max_heap_byte_size;
|
||||||
size_t _min_heap_byte_size;
|
size_t _min_heap_byte_size;
|
||||||
|
|
||||||
size_t _min_alignment;
|
size_t _space_alignment;
|
||||||
size_t _max_alignment;
|
size_t _heap_alignment;
|
||||||
|
|
||||||
|
// Needed to keep information if MaxHeapSize was set on the command line
|
||||||
|
// when the flag value is aligned etc by ergonomics
|
||||||
|
bool _max_heap_size_cmdline;
|
||||||
|
|
||||||
// The sizing of the heap are controlled by a sizing policy.
|
// The sizing of the heap are controlled by a sizing policy.
|
||||||
AdaptiveSizePolicy* _size_policy;
|
AdaptiveSizePolicy* _size_policy;
|
||||||
@ -87,23 +93,20 @@ class CollectorPolicy : public CHeapObj<mtGC> {
|
|||||||
// mem_allocate() where it returns op.result()
|
// mem_allocate() where it returns op.result()
|
||||||
bool _all_soft_refs_clear;
|
bool _all_soft_refs_clear;
|
||||||
|
|
||||||
CollectorPolicy() :
|
CollectorPolicy();
|
||||||
_min_alignment(1),
|
|
||||||
_max_alignment(1),
|
|
||||||
_initial_heap_byte_size(0),
|
|
||||||
_max_heap_byte_size(0),
|
|
||||||
_min_heap_byte_size(0),
|
|
||||||
_size_policy(NULL),
|
|
||||||
_should_clear_all_soft_refs(false),
|
|
||||||
_all_soft_refs_clear(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Return maximum heap alignment that may be imposed by the policy
|
virtual void initialize_all() {
|
||||||
static size_t compute_max_alignment();
|
initialize_alignments();
|
||||||
|
initialize_flags();
|
||||||
|
initialize_size_info();
|
||||||
|
}
|
||||||
|
|
||||||
size_t min_alignment() { return _min_alignment; }
|
// Return maximum heap alignment that may be imposed by the policy
|
||||||
size_t max_alignment() { return _max_alignment; }
|
static size_t compute_heap_alignment();
|
||||||
|
|
||||||
|
size_t space_alignment() { return _space_alignment; }
|
||||||
|
size_t heap_alignment() { return _heap_alignment; }
|
||||||
|
|
||||||
size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
|
size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
|
||||||
size_t max_heap_byte_size() { return _max_heap_byte_size; }
|
size_t max_heap_byte_size() { return _max_heap_byte_size; }
|
||||||
@ -195,6 +198,9 @@ class CollectorPolicy : public CHeapObj<mtGC> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do any updates required to global flags that are due to heap initialization
|
||||||
|
// changes
|
||||||
|
virtual void post_heap_initialize() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClearedAllSoftRefs : public StackObj {
|
class ClearedAllSoftRefs : public StackObj {
|
||||||
@ -219,6 +225,10 @@ class GenCollectorPolicy : public CollectorPolicy {
|
|||||||
size_t _initial_gen0_size;
|
size_t _initial_gen0_size;
|
||||||
size_t _max_gen0_size;
|
size_t _max_gen0_size;
|
||||||
|
|
||||||
|
// _gen_alignment and _space_alignment will have the same value most of the
|
||||||
|
// time. When using large pages they can differ.
|
||||||
|
size_t _gen_alignment;
|
||||||
|
|
||||||
GenerationSpec **_generations;
|
GenerationSpec **_generations;
|
||||||
|
|
||||||
// Return true if an allocation should be attempted in the older
|
// Return true if an allocation should be attempted in the older
|
||||||
@ -229,23 +239,31 @@ class GenCollectorPolicy : public CollectorPolicy {
|
|||||||
void initialize_flags();
|
void initialize_flags();
|
||||||
void initialize_size_info();
|
void initialize_size_info();
|
||||||
|
|
||||||
|
DEBUG_ONLY(void assert_flags();)
|
||||||
|
DEBUG_ONLY(void assert_size_info();)
|
||||||
|
|
||||||
// Try to allocate space by expanding the heap.
|
// Try to allocate space by expanding the heap.
|
||||||
virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
|
virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
|
||||||
|
|
||||||
// Scale the base_size by NewRation according to
|
// Compute max heap alignment
|
||||||
|
size_t compute_max_alignment();
|
||||||
|
|
||||||
|
// Scale the base_size by NewRatio according to
|
||||||
// result = base_size / (NewRatio + 1)
|
// result = base_size / (NewRatio + 1)
|
||||||
// and align by min_alignment()
|
// and align by min_alignment()
|
||||||
size_t scale_by_NewRatio_aligned(size_t base_size);
|
size_t scale_by_NewRatio_aligned(size_t base_size);
|
||||||
|
|
||||||
// Bound the value by the given maximum minus the
|
// Bound the value by the given maximum minus the min_alignment
|
||||||
// min_alignment.
|
|
||||||
size_t bound_minus_alignment(size_t desired_size, size_t maximum_size);
|
size_t bound_minus_alignment(size_t desired_size, size_t maximum_size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
GenCollectorPolicy();
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
size_t min_gen0_size() { return _min_gen0_size; }
|
size_t min_gen0_size() { return _min_gen0_size; }
|
||||||
size_t initial_gen0_size() { return _initial_gen0_size; }
|
size_t initial_gen0_size() { return _initial_gen0_size; }
|
||||||
size_t max_gen0_size() { return _max_gen0_size; }
|
size_t max_gen0_size() { return _max_gen0_size; }
|
||||||
|
size_t gen_alignment() { return _gen_alignment; }
|
||||||
|
|
||||||
virtual int number_of_generations() = 0;
|
virtual int number_of_generations() = 0;
|
||||||
|
|
||||||
@ -256,14 +274,15 @@ class GenCollectorPolicy : public CollectorPolicy {
|
|||||||
|
|
||||||
virtual GenCollectorPolicy* as_generation_policy() { return this; }
|
virtual GenCollectorPolicy* as_generation_policy() { return this; }
|
||||||
|
|
||||||
virtual void initialize_generations() = 0;
|
virtual void initialize_generations() { };
|
||||||
|
|
||||||
virtual void initialize_all() {
|
virtual void initialize_all() {
|
||||||
initialize_flags();
|
CollectorPolicy::initialize_all();
|
||||||
initialize_size_info();
|
|
||||||
initialize_generations();
|
initialize_generations();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t young_gen_size_lower_bound();
|
||||||
|
|
||||||
HeapWord* mem_allocate_work(size_t size,
|
HeapWord* mem_allocate_work(size_t size,
|
||||||
bool is_tlab,
|
bool is_tlab,
|
||||||
bool* gc_overhead_limit_was_exceeded);
|
bool* gc_overhead_limit_was_exceeded);
|
||||||
@ -275,10 +294,8 @@ class GenCollectorPolicy : public CollectorPolicy {
|
|||||||
size_t init_promo_size,
|
size_t init_promo_size,
|
||||||
size_t init_survivor_size);
|
size_t init_survivor_size);
|
||||||
|
|
||||||
// The alignment used for eden and survivors within the young gen
|
virtual void post_heap_initialize() {
|
||||||
// and for boundary between young gen and old gen.
|
assert(_max_gen0_size == MaxNewSize, "Should be taken care of by initialize_size_info");
|
||||||
static size_t intra_heap_alignment() {
|
|
||||||
return 64 * K * HeapWordSize;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -296,9 +313,14 @@ class TwoGenerationCollectorPolicy : public GenCollectorPolicy {
|
|||||||
|
|
||||||
void initialize_flags();
|
void initialize_flags();
|
||||||
void initialize_size_info();
|
void initialize_size_info();
|
||||||
void initialize_generations() { ShouldNotReachHere(); }
|
|
||||||
|
DEBUG_ONLY(void assert_flags();)
|
||||||
|
DEBUG_ONLY(void assert_size_info();)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
TwoGenerationCollectorPolicy() : GenCollectorPolicy(), _min_gen1_size(0),
|
||||||
|
_initial_gen1_size(0), _max_gen1_size(0) {}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
size_t min_gen1_size() { return _min_gen1_size; }
|
size_t min_gen1_size() { return _min_gen1_size; }
|
||||||
size_t initial_gen1_size() { return _initial_gen1_size; }
|
size_t initial_gen1_size() { return _initial_gen1_size; }
|
||||||
@ -321,10 +343,11 @@ class TwoGenerationCollectorPolicy : public GenCollectorPolicy {
|
|||||||
|
|
||||||
class MarkSweepPolicy : public TwoGenerationCollectorPolicy {
|
class MarkSweepPolicy : public TwoGenerationCollectorPolicy {
|
||||||
protected:
|
protected:
|
||||||
|
void initialize_alignments();
|
||||||
void initialize_generations();
|
void initialize_generations();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MarkSweepPolicy();
|
MarkSweepPolicy() {}
|
||||||
|
|
||||||
MarkSweepPolicy* as_mark_sweep_policy() { return this; }
|
MarkSweepPolicy* as_mark_sweep_policy() { return this; }
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs,
|
|||||||
// Compute the maximum eden and survivor space sizes. These sizes
|
// Compute the maximum eden and survivor space sizes. These sizes
|
||||||
// are computed assuming the entire reserved space is committed.
|
// are computed assuming the entire reserved space is committed.
|
||||||
// These values are exported as performance counters.
|
// These values are exported as performance counters.
|
||||||
uintx alignment = GenCollectedHeap::heap()->collector_policy()->min_alignment();
|
uintx alignment = GenCollectedHeap::heap()->collector_policy()->space_alignment();
|
||||||
uintx size = _virtual_space.reserved_size();
|
uintx size = _virtual_space.reserved_size();
|
||||||
_max_survivor_size = compute_survivor_size(size, alignment);
|
_max_survivor_size = compute_survivor_size(size, alignment);
|
||||||
_max_eden_size = size - (2*_max_survivor_size);
|
_max_eden_size = size - (2*_max_survivor_size);
|
||||||
@ -235,7 +235,7 @@ void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size,
|
|||||||
bool clear_space,
|
bool clear_space,
|
||||||
bool mangle_space) {
|
bool mangle_space) {
|
||||||
uintx alignment =
|
uintx alignment =
|
||||||
GenCollectedHeap::heap()->collector_policy()->min_alignment();
|
GenCollectedHeap::heap()->collector_policy()->space_alignment();
|
||||||
|
|
||||||
// If the spaces are being cleared (only done at heap initialization
|
// If the spaces are being cleared (only done at heap initialization
|
||||||
// currently), the survivor spaces need not be empty.
|
// currently), the survivor spaces need not be empty.
|
||||||
@ -473,7 +473,7 @@ size_t DefNewGeneration::free() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t DefNewGeneration::max_capacity() const {
|
size_t DefNewGeneration::max_capacity() const {
|
||||||
const size_t alignment = GenCollectedHeap::heap()->collector_policy()->min_alignment();
|
const size_t alignment = GenCollectedHeap::heap()->collector_policy()->space_alignment();
|
||||||
const size_t reserved_bytes = reserved().byte_size();
|
const size_t reserved_bytes = reserved().byte_size();
|
||||||
return reserved_bytes - compute_survivor_size(reserved_bytes, alignment);
|
return reserved_bytes - compute_survivor_size(reserved_bytes, alignment);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ jint GenCollectedHeap::initialize() {
|
|||||||
int n_covered_regions = 0;
|
int n_covered_regions = 0;
|
||||||
ReservedSpace heap_rs;
|
ReservedSpace heap_rs;
|
||||||
|
|
||||||
size_t heap_alignment = collector_policy()->max_alignment();
|
size_t heap_alignment = collector_policy()->heap_alignment();
|
||||||
|
|
||||||
heap_address = allocate(heap_alignment, &total_reserved,
|
heap_address = allocate(heap_alignment, &total_reserved,
|
||||||
&n_covered_regions, &heap_rs);
|
&n_covered_regions, &heap_rs);
|
||||||
|
@ -247,6 +247,7 @@ void SharedHeap::set_barrier_set(BarrierSet* bs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SharedHeap::post_initialize() {
|
void SharedHeap::post_initialize() {
|
||||||
|
CollectedHeap::post_initialize();
|
||||||
ref_processing_init();
|
ref_processing_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,6 +765,7 @@ jint Universe::initialize_heap() {
|
|||||||
} else if (UseG1GC) {
|
} else if (UseG1GC) {
|
||||||
#if INCLUDE_ALL_GCS
|
#if INCLUDE_ALL_GCS
|
||||||
G1CollectorPolicy* g1p = new G1CollectorPolicy();
|
G1CollectorPolicy* g1p = new G1CollectorPolicy();
|
||||||
|
g1p->initialize_all();
|
||||||
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
|
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
|
||||||
Universe::_collectedHeap = g1h;
|
Universe::_collectedHeap = g1h;
|
||||||
#else // INCLUDE_ALL_GCS
|
#else // INCLUDE_ALL_GCS
|
||||||
@ -789,6 +790,7 @@ jint Universe::initialize_heap() {
|
|||||||
} else { // default old generation
|
} else { // default old generation
|
||||||
gc_policy = new MarkSweepPolicy();
|
gc_policy = new MarkSweepPolicy();
|
||||||
}
|
}
|
||||||
|
gc_policy->initialize_all();
|
||||||
|
|
||||||
Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
|
Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
|
|||||||
gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
|
gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap "
|
||||||
SIZE_FORMAT" Maximum heap "SIZE_FORMAT" Min alignment "SIZE_FORMAT" Max alignment "SIZE_FORMAT,
|
SIZE_FORMAT" Maximum heap "SIZE_FORMAT" Min alignment "SIZE_FORMAT" Max alignment "SIZE_FORMAT,
|
||||||
p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(),
|
p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(),
|
||||||
p->min_alignment(), p->max_alignment());
|
p->space_alignment(), p->heap_alignment());
|
||||||
}
|
}
|
||||||
WB_END
|
WB_END
|
||||||
|
|
||||||
|
@ -1505,7 +1505,7 @@ void Arguments::set_conservative_max_heap_alignment() {
|
|||||||
}
|
}
|
||||||
#endif // INCLUDE_ALL_GCS
|
#endif // INCLUDE_ALL_GCS
|
||||||
_conservative_max_heap_alignment = MAX3(heap_alignment, os::max_page_size(),
|
_conservative_max_heap_alignment = MAX3(heap_alignment, os::max_page_size(),
|
||||||
CollectorPolicy::compute_max_alignment());
|
CollectorPolicy::compute_heap_alignment());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Arguments::set_ergonomics_flags() {
|
void Arguments::set_ergonomics_flags() {
|
||||||
@ -2165,6 +2165,10 @@ bool Arguments::check_vm_args_consistency() {
|
|||||||
|
|
||||||
#if INCLUDE_ALL_GCS
|
#if INCLUDE_ALL_GCS
|
||||||
if (UseG1GC) {
|
if (UseG1GC) {
|
||||||
|
status = status && verify_percentage(G1NewSizePercent, "G1NewSizePercent");
|
||||||
|
status = status && verify_percentage(G1MaxNewSizePercent, "G1MaxNewSizePercent");
|
||||||
|
status = status && verify_interval(G1NewSizePercent, 0, G1MaxNewSizePercent, "G1NewSizePercent");
|
||||||
|
|
||||||
status = status && verify_percentage(InitiatingHeapOccupancyPercent,
|
status = status && verify_percentage(InitiatingHeapOccupancyPercent,
|
||||||
"InitiatingHeapOccupancyPercent");
|
"InitiatingHeapOccupancyPercent");
|
||||||
status = status && verify_min_value(G1RefProcDrainInterval, 1,
|
status = status && verify_min_value(G1RefProcDrainInterval, 1,
|
||||||
|
@ -64,32 +64,29 @@ class TestMaxHeapSizeTools {
|
|||||||
long newPlusOldSize = values[0] + values[1];
|
long newPlusOldSize = values[0] + values[1];
|
||||||
long smallValue = newPlusOldSize / 2;
|
long smallValue = newPlusOldSize / 2;
|
||||||
long largeValue = newPlusOldSize * 2;
|
long largeValue = newPlusOldSize * 2;
|
||||||
|
long maxHeapSize = largeValue + (2 * 1024 * 1024);
|
||||||
|
|
||||||
// -Xms is not set
|
// -Xms is not set
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M" }, values, -1, -1);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize }, values, -1, -1);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-XX:InitialHeapSize=" + smallValue }, values, -1, smallValue);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=" + largeValue }, values, -1, largeValue);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-XX:InitialHeapSize=" + largeValue }, values, -1, largeValue);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-XX:InitialHeapSize=0" }, values, -1, -1);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-XX:InitialHeapSize=0" }, values, -1, -1);
|
||||||
|
|
||||||
// -Xms is set to zero
|
// -Xms is set to zero
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0" }, values, -1, -1);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms0" }, values, -1, -1);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms0", "-XX:InitialHeapSize=" + smallValue }, values, -1, smallValue);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=" + largeValue }, values, -1, largeValue);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms0", "-XX:InitialHeapSize=" + largeValue }, values, -1, largeValue);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms0", "-XX:InitialHeapSize=0" }, values, -1, -1);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms0", "-XX:InitialHeapSize=0" }, values, -1, -1);
|
||||||
|
|
||||||
// -Xms is set to small value
|
// -Xms is set to small value
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue }, values, -1, -1);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms" + smallValue }, values, -1, -1);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms" + smallValue, "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=" + largeValue }, values, smallValue, largeValue);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms" + smallValue, "-XX:InitialHeapSize=" + largeValue }, values, smallValue, largeValue);
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + smallValue, "-XX:InitialHeapSize=0" }, values, smallValue, -1);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms" + smallValue, "-XX:InitialHeapSize=0" }, values, smallValue, -1);
|
||||||
|
|
||||||
// -Xms is set to large value
|
// -Xms is set to large value
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue }, values, largeValue, largeValue);
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms" + largeValue }, values, largeValue, largeValue);
|
||||||
// the next case has already been checked elsewhere and gives an error
|
checkErgonomics(new String[] { gcflag, "-Xmx" + maxHeapSize, "-Xms" + largeValue, "-XX:InitialHeapSize=0" }, values, largeValue, -1);
|
||||||
// checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=" + smallValue }, values, smallValue, smallValue);
|
|
||||||
// the next case has already been checked elsewhere too
|
|
||||||
// checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=" + largeValue }, values, values[0], largeValue);
|
|
||||||
checkErgonomics(new String[] { gcflag, "-Xmx16M", "-Xms" + largeValue, "-XX:InitialHeapSize=0" }, values, largeValue, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long align_up(long value, long alignment) {
|
private static long align_up(long value, long alignment) {
|
||||||
|
122
hotspot/test/gc/arguments/TestMaxNewSize.java
Normal file
122
hotspot/test/gc/arguments/TestMaxNewSize.java
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test TestMaxNewSize
|
||||||
|
* @key gc
|
||||||
|
* @bug 7057939
|
||||||
|
* @summary Make sure that MaxNewSize always has a useful value after argument
|
||||||
|
* processing.
|
||||||
|
* @library /testlibrary
|
||||||
|
* @build TestMaxNewSize
|
||||||
|
* @run main TestMaxNewSize -XX:+UseSerialGC
|
||||||
|
* @run main TestMaxNewSize -XX:+UseParallelGC
|
||||||
|
* @run main TestMaxNewSize -XX:+UseConcMarkSweepGC
|
||||||
|
* @run main TestMaxNewSize -XX:+UseG1GC
|
||||||
|
* @author thomas.schatzl@oracle.com, jesper.wilhelmsson@oracle.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.*;
|
||||||
|
|
||||||
|
public class TestMaxNewSize {
|
||||||
|
|
||||||
|
private static void checkMaxNewSize(String[] flags, int heapsize) throws Exception {
|
||||||
|
BigInteger actual = new BigInteger(getMaxNewSize(flags));
|
||||||
|
System.out.println(actual);
|
||||||
|
if (actual.compareTo(new BigInteger((new Long(heapsize)).toString())) == 1) {
|
||||||
|
throw new RuntimeException("MaxNewSize value set to \"" + actual +
|
||||||
|
"\", expected otherwise when running with the following flags: " + Arrays.asList(flags).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkIncompatibleNewSize(String[] flags) throws Exception {
|
||||||
|
ArrayList<String> finalargs = new ArrayList<String>();
|
||||||
|
finalargs.addAll(Arrays.asList(flags));
|
||||||
|
finalargs.add("-version");
|
||||||
|
|
||||||
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
|
||||||
|
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||||
|
output.shouldContain("Initial young gen size set larger than the maximum young gen size");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isRunningG1(String[] args) {
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
if (args[i].contains("+UseG1GC")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getMaxNewSize(String[] flags) throws Exception {
|
||||||
|
ArrayList<String> finalargs = new ArrayList<String>();
|
||||||
|
finalargs.addAll(Arrays.asList(flags));
|
||||||
|
if (isRunningG1(flags)) {
|
||||||
|
finalargs.add("-XX:G1HeapRegionSize=1M");
|
||||||
|
}
|
||||||
|
finalargs.add("-XX:+PrintFlagsFinal");
|
||||||
|
finalargs.add("-version");
|
||||||
|
|
||||||
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(finalargs.toArray(new String[0]));
|
||||||
|
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||||
|
output.shouldHaveExitValue(0);
|
||||||
|
String stdout = output.getStdout();
|
||||||
|
//System.out.println(stdout);
|
||||||
|
return getFlagValue("MaxNewSize", stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getFlagValue(String flag, String where) {
|
||||||
|
Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
|
||||||
|
if (!m.find()) {
|
||||||
|
throw new RuntimeException("Could not find value for flag " + flag + " in output string");
|
||||||
|
}
|
||||||
|
String match = m.group();
|
||||||
|
return match.substring(match.lastIndexOf(" ") + 1, match.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Exception {
|
||||||
|
String gcName = args[0];
|
||||||
|
final int M32 = 32 * 1024 * 1024;
|
||||||
|
final int M64 = 64 * 1024 * 1024;
|
||||||
|
final int M96 = 96 * 1024 * 1024;
|
||||||
|
final int M128 = 128 * 1024 * 1024;
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx128M" }, M128);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx128M", "-XX:NewRatio=5" }, M128);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx128M", "-XX:NewSize=32M" }, M128);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx128M", "-XX:OldSize=96M" }, M128);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx128M", "-XX:MaxNewSize=32M" }, M32);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx128M", "-XX:NewSize=32M", "-XX:MaxNewSize=32M" }, M32);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx128M", "-XX:NewRatio=6", "-XX:MaxNewSize=32M" }, M32);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx128M", "-Xms96M" }, M128);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-Xmx96M", "-Xms96M" }, M96);
|
||||||
|
checkMaxNewSize(new String[] { gcName, "-XX:NewSize=128M", "-XX:MaxNewSize=50M"}, M128);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user