提交 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) { ...@@ -1682,7 +1682,7 @@ bool G1CollectedHeap::expand(size_t expand_bytes) {
} }
assert(curr == mr.end(), "post-condition"); assert(curr == mr.end(), "post-condition");
} }
g1_policy()->calculate_reserve(n_regions()); g1_policy()->record_new_heap_size(n_regions());
} else { } else {
ergo_verbose0(ErgoHeapSizing, ergo_verbose0(ErgoHeapSizing,
"did not expand the heap", "did not expand the heap",
...@@ -1733,7 +1733,7 @@ void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { ...@@ -1733,7 +1733,7 @@ void G1CollectedHeap::shrink_helper(size_t shrink_bytes) {
_expansion_regions += num_regions_deleted; _expansion_regions += num_regions_deleted;
update_committed_space(old_end, new_end); update_committed_space(old_end, new_end);
HeapRegionRemSet::shrink_heap(n_regions()); HeapRegionRemSet::shrink_heap(n_regions());
g1_policy()->calculate_reserve(n_regions()); g1_policy()->record_new_heap_size(n_regions());
} else { } else {
ergo_verbose0(ErgoHeapSizing, ergo_verbose0(ErgoHeapSizing,
"did not shrink the heap", "did not shrink the heap",
...@@ -3525,6 +3525,19 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { ...@@ -3525,6 +3525,19 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
init_mutator_alloc_region(); 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 end_time_sec = os::elapsedTime();
double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS; double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
g1_policy()->record_pause_time_ms(pause_time_ms); g1_policy()->record_pause_time_ms(pause_time_ms);
......
...@@ -146,6 +146,7 @@ G1CollectorPolicy::G1CollectorPolicy() : ...@@ -146,6 +146,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
_stop_world_start(0.0), _stop_world_start(0.0),
_all_stop_world_times_ms(new NumberSeq()), _all_stop_world_times_ms(new NumberSeq()),
_all_yield_times_ms(new NumberSeq()), _all_yield_times_ms(new NumberSeq()),
_using_new_ratio_calculations(false),
_all_mod_union_times_ms(new NumberSeq()), _all_mod_union_times_ms(new NumberSeq()),
...@@ -430,7 +431,7 @@ G1CollectorPolicy::G1CollectorPolicy() : ...@@ -430,7 +431,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
"it's been updated to %u", reserve_perc); "it's been updated to %u", reserve_perc);
} }
_reserve_factor = (double) reserve_perc / 100.0; _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. // for the first time during initialization.
_reserve_regions = 0; _reserve_regions = 0;
...@@ -458,16 +459,15 @@ void G1CollectorPolicy::initialize_flags() { ...@@ -458,16 +459,15 @@ void G1CollectorPolicy::initialize_flags() {
// ParallelScavengeHeap::initialize()). We might change this in the // ParallelScavengeHeap::initialize()). We might change this in the
// future, but it's a good start. // future, but it's a good start.
class G1YoungGenSizer : public TwoGenerationCollectorPolicy { class G1YoungGenSizer : public TwoGenerationCollectorPolicy {
size_t size_to_region_num(size_t byte_size) {
return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
}
public: public:
G1YoungGenSizer() { G1YoungGenSizer() {
initialize_flags(); initialize_flags();
initialize_size_info(); 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() { size_t min_young_region_num() {
return size_to_region_num(_min_gen0_size); return size_to_region_num(_min_gen0_size);
} }
...@@ -479,6 +479,13 @@ public: ...@@ -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() { void G1CollectorPolicy::init() {
// Set aside an initial future to_space. // Set aside an initial future to_space.
_g1 = G1CollectedHeap::heap(); _g1 = G1CollectedHeap::heap();
...@@ -489,16 +496,35 @@ void G1CollectorPolicy::init() { ...@@ -489,16 +496,35 @@ void G1CollectorPolicy::init() {
G1YoungGenSizer sizer; G1YoungGenSizer sizer;
size_t initial_region_num = sizer.initial_young_region_num(); 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) { if (FLAG_IS_CMDLINE(NewRatio)) {
set_adaptive_young_list_length(true); 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; _young_list_fixed_length = 0;
} else { } else {
set_adaptive_young_list_length(false);
_young_list_fixed_length = initial_region_num; _young_list_fixed_length = initial_region_num;
} }
_free_regions_at_end_of_collection = _g1->free_regions(); _free_regions_at_end_of_collection = _g1->free_regions();
update_young_list_target_length(); 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 // We may immediately start allocating regions and placing them on the
// collection set list. Initialize the per-collection set info // collection set list. Initialize the per-collection set info
...@@ -541,11 +567,18 @@ bool G1CollectorPolicy::predict_will_fit(size_t young_length, ...@@ -541,11 +567,18 @@ bool G1CollectorPolicy::predict_will_fit(size_t young_length,
return true; return true;
} }
void G1CollectorPolicy::calculate_reserve(size_t all_regions) { void G1CollectorPolicy::record_new_heap_size(size_t new_number_of_regions) {
double reserve_regions_d = (double) all_regions * _reserve_factor; // 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 // We use ceiling so that if reserve_regions_d is > 0.0 (but
// smaller than 1.0) we'll get 1. // smaller than 1.0) we'll get 1.
_reserve_regions = (size_t) ceil(reserve_regions_d); _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( size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
...@@ -561,16 +594,16 @@ 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 // otherwise we don't have enough info to make the prediction
} }
} }
// Here, we might want to also take into account any additional desired_min_length += base_min_length;
// constraints (i.e., user-defined minimum bound). Currently, we don't. // make sure we don't go below any user-defined minimum bound
return base_min_length + desired_min_length; return MAX2(_min_desired_young_length, desired_min_length);
} }
size_t G1CollectorPolicy::calculate_young_list_desired_max_length() { size_t G1CollectorPolicy::calculate_young_list_desired_max_length() {
// Here, we might want to also take into account any additional // Here, we might want to also take into account any additional
// constraints (i.e., user-defined minimum bound). Currently, we // constraints (i.e., user-defined minimum bound). Currently, we
// effectively don't set this bound. // 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) { void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {
...@@ -1699,20 +1732,26 @@ void G1CollectorPolicy::print_heap_transition() { ...@@ -1699,20 +1732,26 @@ void G1CollectorPolicy::print_heap_transition() {
size_t used_before_gc = _cur_collection_pause_used_at_start_bytes; size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
size_t used = _g1->used(); size_t used = _g1->used();
size_t capacity = _g1->capacity(); size_t capacity = _g1->capacity();
size_t eden_capacity =
(_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
gclog_or_tty->print_cr( 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" " "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
"Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->" "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]", EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
EXT_SIZE_PARAMS(_eden_bytes_before_gc), EXT_SIZE_PARAMS(_eden_bytes_before_gc),
EXT_SIZE_PARAMS(_prev_eden_capacity),
EXT_SIZE_PARAMS(eden_bytes), EXT_SIZE_PARAMS(eden_bytes),
EXT_SIZE_PARAMS(eden_capacity),
EXT_SIZE_PARAMS(_survivor_bytes_before_gc), EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
EXT_SIZE_PARAMS(survivor_bytes), EXT_SIZE_PARAMS(survivor_bytes),
EXT_SIZE_PARAMS(used_before_gc), EXT_SIZE_PARAMS(used_before_gc),
EXT_SIZE_PARAMS(_capacity_before_gc), EXT_SIZE_PARAMS(_capacity_before_gc),
EXT_SIZE_PARAMS(used), EXT_SIZE_PARAMS(used),
EXT_SIZE_PARAMS(capacity)); EXT_SIZE_PARAMS(capacity));
_prev_eden_capacity = eden_capacity;
} else if (PrintGC) { } else if (PrintGC) {
_g1->print_size_transition(gclog_or_tty, _g1->print_size_transition(gclog_or_tty,
_cur_collection_pause_used_at_start_bytes, _cur_collection_pause_used_at_start_bytes,
......
...@@ -185,6 +185,7 @@ protected: ...@@ -185,6 +185,7 @@ protected:
bool _adaptive_young_list_length; bool _adaptive_young_list_length;
size_t _young_list_target_length; size_t _young_list_target_length;
size_t _young_list_fixed_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 // The max number of regions we can extend the eden by while the GC
// locker is active. This should be >= _young_list_target_length; // locker is active. This should be >= _young_list_target_length;
...@@ -245,6 +246,10 @@ private: ...@@ -245,6 +246,10 @@ private:
TruncatedSeq* _max_conc_overhead_seq; 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_young_regions;
size_t _recorded_non_young_regions; size_t _recorded_non_young_regions;
size_t _recorded_region_num; size_t _recorded_region_num;
...@@ -826,9 +831,8 @@ public: ...@@ -826,9 +831,8 @@ public:
return _all_pause_times_ms->num() + 1; return _all_pause_times_ms->num() + 1;
} }
// Recalculate the reserve region number. This should be called // This should be called after the heap is resized.
// after the heap is resized. void record_new_heap_size(size_t new_number_of_regions);
void calculate_reserve(size_t all_regions);
protected: protected:
...@@ -841,6 +845,8 @@ protected: ...@@ -841,6 +845,8 @@ protected:
size_t max_live_bytes); size_t max_live_bytes);
void record_concurrent_mark_cleanup_end_work2(); void record_concurrent_mark_cleanup_end_work2();
void update_young_list_size_using_newratio(size_t number_of_heap_regions);
public: public:
virtual void init(); virtual void init();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册