提交 499845d6 编写于 作者: B brutisso

6929868: G1: introduce min / max young gen size bounds

Summary: Make G1 handle young gen size command line flags more consistently
Reviewed-by: tonyp, jwilhelm
上级 389cad56
......@@ -1682,7 +1682,7 @@ bool G1CollectedHeap::expand(size_t expand_bytes) {
}
assert(curr == mr.end(), "post-condition");
}
g1_policy()->calculate_reserve(n_regions());
g1_policy()->record_new_heap_size(n_regions());
} else {
ergo_verbose0(ErgoHeapSizing,
"did not expand the heap",
......@@ -1733,7 +1733,7 @@ void G1CollectedHeap::shrink_helper(size_t shrink_bytes) {
_expansion_regions += num_regions_deleted;
update_committed_space(old_end, new_end);
HeapRegionRemSet::shrink_heap(n_regions());
g1_policy()->calculate_reserve(n_regions());
g1_policy()->record_new_heap_size(n_regions());
} else {
ergo_verbose0(ErgoHeapSizing,
"did not shrink the heap",
......@@ -3525,6 +3525,19 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
init_mutator_alloc_region();
{
size_t expand_bytes = g1_policy()->expansion_amount();
if (expand_bytes > 0) {
size_t bytes_before = capacity();
if (!expand(expand_bytes)) {
// We failed to expand the heap so let's verify that
// committed/uncommitted amount match the backing store
assert(capacity() == _g1_storage.committed_size(), "committed size mismatch");
assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch");
}
}
}
double end_time_sec = os::elapsedTime();
double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
g1_policy()->record_pause_time_ms(pause_time_ms);
......
......@@ -146,6 +146,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
_stop_world_start(0.0),
_all_stop_world_times_ms(new NumberSeq()),
_all_yield_times_ms(new NumberSeq()),
_using_new_ratio_calculations(false),
_all_mod_union_times_ms(new NumberSeq()),
......@@ -430,7 +431,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
"it's been updated to %u", reserve_perc);
}
_reserve_factor = (double) reserve_perc / 100.0;
// This will be set in calculate_reserve() when the heap is expanded
// This will be set when the heap is expanded
// for the first time during initialization.
_reserve_regions = 0;
......@@ -458,16 +459,15 @@ void G1CollectorPolicy::initialize_flags() {
// ParallelScavengeHeap::initialize()). We might change this in the
// future, but it's a good start.
class G1YoungGenSizer : public TwoGenerationCollectorPolicy {
size_t size_to_region_num(size_t byte_size) {
return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
}
public:
G1YoungGenSizer() {
initialize_flags();
initialize_size_info();
}
size_t size_to_region_num(size_t byte_size) {
return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
}
size_t min_young_region_num() {
return size_to_region_num(_min_gen0_size);
}
......@@ -479,6 +479,13 @@ public:
}
};
void G1CollectorPolicy::update_young_list_size_using_newratio(size_t number_of_heap_regions) {
assert(number_of_heap_regions > 0, "Heap must be initialized");
size_t young_size = number_of_heap_regions / (NewRatio + 1);
_min_desired_young_length = young_size;
_max_desired_young_length = young_size;
}
void G1CollectorPolicy::init() {
// Set aside an initial future to_space.
_g1 = G1CollectedHeap::heap();
......@@ -489,16 +496,35 @@ void G1CollectorPolicy::init() {
G1YoungGenSizer sizer;
size_t initial_region_num = sizer.initial_young_region_num();
_min_desired_young_length = sizer.min_young_region_num();
_max_desired_young_length = sizer.max_young_region_num();
if (UseAdaptiveSizePolicy) {
set_adaptive_young_list_length(true);
if (FLAG_IS_CMDLINE(NewRatio)) {
if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
gclog_or_tty->print_cr("-XX:NewSize and -XX:MaxNewSize overrides -XX:NewRatio");
} else {
// Treat NewRatio as a fixed size that is only recalculated when the heap size changes
size_t heap_regions = sizer.size_to_region_num(_g1->n_regions());
update_young_list_size_using_newratio(heap_regions);
_using_new_ratio_calculations = true;
}
}
// GenCollectorPolicy guarantees that min <= initial <= max.
// Asserting here just to state that we rely on this property.
assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values");
assert(initial_region_num <= _max_desired_young_length, "Initial young gen size too large");
assert(_min_desired_young_length <= initial_region_num, "Initial young gen size too small");
set_adaptive_young_list_length(_min_desired_young_length < _max_desired_young_length);
if (adaptive_young_list_length()) {
_young_list_fixed_length = 0;
} else {
set_adaptive_young_list_length(false);
_young_list_fixed_length = initial_region_num;
}
_free_regions_at_end_of_collection = _g1->free_regions();
update_young_list_target_length();
_prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes;
// We may immediately start allocating regions and placing them on the
// collection set list. Initialize the per-collection set info
......@@ -541,11 +567,18 @@ bool G1CollectorPolicy::predict_will_fit(size_t young_length,
return true;
}
void G1CollectorPolicy::calculate_reserve(size_t all_regions) {
double reserve_regions_d = (double) all_regions * _reserve_factor;
void G1CollectorPolicy::record_new_heap_size(size_t new_number_of_regions) {
// re-calculate the necessary reserve
double reserve_regions_d = (double) new_number_of_regions * _reserve_factor;
// We use ceiling so that if reserve_regions_d is > 0.0 (but
// smaller than 1.0) we'll get 1.
_reserve_regions = (size_t) ceil(reserve_regions_d);
if (_using_new_ratio_calculations) {
// -XX:NewRatio was specified so we need to update the
// young gen length when the heap size has changed.
update_young_list_size_using_newratio(new_number_of_regions);
}
}
size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
......@@ -561,16 +594,16 @@ size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
// otherwise we don't have enough info to make the prediction
}
}
// Here, we might want to also take into account any additional
// constraints (i.e., user-defined minimum bound). Currently, we don't.
return base_min_length + desired_min_length;
desired_min_length += base_min_length;
// make sure we don't go below any user-defined minimum bound
return MAX2(_min_desired_young_length, desired_min_length);
}
size_t G1CollectorPolicy::calculate_young_list_desired_max_length() {
// Here, we might want to also take into account any additional
// constraints (i.e., user-defined minimum bound). Currently, we
// effectively don't set this bound.
return _g1->n_regions();
return _max_desired_young_length;
}
void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {
......@@ -1699,20 +1732,26 @@ void G1CollectorPolicy::print_heap_transition() {
size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
size_t used = _g1->used();
size_t capacity = _g1->capacity();
size_t eden_capacity =
(_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
gclog_or_tty->print_cr(
" [Eden: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
" [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
"Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
"Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
EXT_SIZE_PARAMS(_eden_bytes_before_gc),
EXT_SIZE_PARAMS(_prev_eden_capacity),
EXT_SIZE_PARAMS(eden_bytes),
EXT_SIZE_PARAMS(eden_capacity),
EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
EXT_SIZE_PARAMS(survivor_bytes),
EXT_SIZE_PARAMS(used_before_gc),
EXT_SIZE_PARAMS(_capacity_before_gc),
EXT_SIZE_PARAMS(used),
EXT_SIZE_PARAMS(capacity));
_prev_eden_capacity = eden_capacity;
} else if (PrintGC) {
_g1->print_size_transition(gclog_or_tty,
_cur_collection_pause_used_at_start_bytes,
......
......@@ -185,6 +185,7 @@ protected:
bool _adaptive_young_list_length;
size_t _young_list_target_length;
size_t _young_list_fixed_length;
size_t _prev_eden_capacity; // used for logging
// The max number of regions we can extend the eden by while the GC
// locker is active. This should be >= _young_list_target_length;
......@@ -245,6 +246,10 @@ private:
TruncatedSeq* _max_conc_overhead_seq;
bool _using_new_ratio_calculations;
size_t _min_desired_young_length; // as set on the command line or default calculations
size_t _max_desired_young_length; // as set on the command line or default calculations
size_t _recorded_young_regions;
size_t _recorded_non_young_regions;
size_t _recorded_region_num;
......@@ -826,9 +831,8 @@ public:
return _all_pause_times_ms->num() + 1;
}
// Recalculate the reserve region number. This should be called
// after the heap is resized.
void calculate_reserve(size_t all_regions);
// This should be called after the heap is resized.
void record_new_heap_size(size_t new_number_of_regions);
protected:
......@@ -841,6 +845,8 @@ protected:
size_t max_live_bytes);
void record_concurrent_mark_cleanup_end_work2();
void update_young_list_size_using_newratio(size_t number_of_heap_regions);
public:
virtual void init();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册