mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-28 08:39:56 +00:00
8380656: G1: Refactor G1IHOPControl
Co-authored-by: Thomas Schatzl <tschatzl@openjdk.org> Reviewed-by: ayang, tschatzl
This commit is contained in:
parent
cca8c23871
commit
b242eef312
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2026, 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
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
// Used to track time from the end of concurrent start to the first mixed GC.
|
||||
// After calling the concurrent start/mixed gc notifications, the result can be
|
||||
// obtained in last_marking_time() once, after which the tracking resets.
|
||||
// obtained in get_and_reset_last_marking_time() once, after which the tracking resets.
|
||||
// Any pauses recorded by add_pause() will be subtracted from that results.
|
||||
class G1ConcurrentStartToMixedTimeTracker {
|
||||
private:
|
||||
@ -60,7 +60,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
double last_marking_time() {
|
||||
double get_and_reset_last_marking_time() {
|
||||
assert(has_result(), "Do not have all measurements yet.");
|
||||
double result = (_mixed_start_time - _concurrent_start_end_time) - _total_pause_time;
|
||||
reset();
|
||||
@ -80,6 +80,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool is_active() const { return _active; }
|
||||
|
||||
// Returns whether we have a result that can be retrieved.
|
||||
bool has_result() const { return _mixed_start_time > 0.0 && _concurrent_start_end_time > 0.0; }
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2026, 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
|
||||
@ -38,18 +38,18 @@ double G1IHOPControl::predict(const TruncatedSeq* seq) const {
|
||||
bool G1IHOPControl::have_enough_data_for_prediction() const {
|
||||
assert(_is_adaptive, "precondition");
|
||||
|
||||
return ((size_t)_marking_times_s.num() >= G1AdaptiveIHOPNumInitialSamples) &&
|
||||
((size_t)_allocation_rate_s.num() >= G1AdaptiveIHOPNumInitialSamples);
|
||||
return ((size_t)_marking_start_to_mixed_time_s.num() >= G1AdaptiveIHOPNumInitialSamples) &&
|
||||
((size_t)_old_gen_alloc_rate.num() >= G1AdaptiveIHOPNumInitialSamples);
|
||||
}
|
||||
|
||||
double G1IHOPControl::last_marking_length_s() const {
|
||||
return _marking_times_s.last();
|
||||
double G1IHOPControl::last_marking_start_to_mixed_time_s() const {
|
||||
return _marking_start_to_mixed_time_s.last();
|
||||
}
|
||||
|
||||
size_t G1IHOPControl::actual_target_threshold() const {
|
||||
size_t G1IHOPControl::effective_target_occupancy() const {
|
||||
assert(_is_adaptive, "precondition");
|
||||
|
||||
// The actual target threshold takes the heap reserve and the expected waste in
|
||||
// The effective target occupancy takes the heap reserve and the expected waste in
|
||||
// free space into account.
|
||||
// _heap_reserve is that part of the total heap capacity that is reserved for
|
||||
// eventual promotion failure.
|
||||
@ -79,9 +79,9 @@ G1IHOPControl::G1IHOPControl(double ihop_percent,
|
||||
_last_allocation_time_s(0.0),
|
||||
_old_gen_alloc_tracker(old_gen_alloc_tracker),
|
||||
_predictor(predictor),
|
||||
_marking_times_s(10, 0.05),
|
||||
_allocation_rate_s(10, 0.05),
|
||||
_last_unrestrained_young_size(0) {
|
||||
_marking_start_to_mixed_time_s(10, 0.05),
|
||||
_old_gen_alloc_rate(10, 0.05),
|
||||
_expected_young_gen_at_first_mixed_gc(0) {
|
||||
assert(_initial_ihop_percent >= 0.0 && _initial_ihop_percent <= 100.0,
|
||||
"IHOP percent out of range: %.3f", ihop_percent);
|
||||
assert(!_is_adaptive || _predictor != nullptr, "precondition");
|
||||
@ -98,85 +98,104 @@ void G1IHOPControl::report_statistics(G1NewTracer* new_tracer, size_t non_young_
|
||||
send_trace_event(new_tracer, non_young_occupancy);
|
||||
}
|
||||
|
||||
void G1IHOPControl::update_allocation_info(double allocation_time_s, size_t additional_buffer_size) {
|
||||
void G1IHOPControl::update_allocation_info(double allocation_time_s, size_t expected_young_gen_size) {
|
||||
assert(allocation_time_s > 0, "Invalid allocation time: %.3f", allocation_time_s);
|
||||
_last_allocation_time_s = allocation_time_s;
|
||||
double alloc_rate = _old_gen_alloc_tracker->last_period_old_gen_growth() / allocation_time_s;
|
||||
_allocation_rate_s.add(alloc_rate);
|
||||
_last_unrestrained_young_size = additional_buffer_size;
|
||||
_old_gen_alloc_rate.add(alloc_rate);
|
||||
_expected_young_gen_at_first_mixed_gc = expected_young_gen_size;
|
||||
}
|
||||
|
||||
void G1IHOPControl::update_marking_length(double marking_length_s) {
|
||||
assert(marking_length_s >= 0.0, "Invalid marking length: %.3f", marking_length_s);
|
||||
_marking_times_s.add(marking_length_s);
|
||||
void G1IHOPControl::add_marking_start_to_mixed_length(double length_s) {
|
||||
assert(length_s >= 0.0, "Invalid marking length: %.3f", length_s);
|
||||
_marking_start_to_mixed_time_s.add(length_s);
|
||||
}
|
||||
|
||||
size_t G1IHOPControl::get_conc_mark_start_threshold() {
|
||||
// Determine the old generation occupancy threshold at which to start
|
||||
// concurrent marking such that reclamation (first Mixed GC) begins
|
||||
// before the heap reaches a critical occupancy level.
|
||||
size_t G1IHOPControl::old_gen_threshold_for_conc_mark_start() {
|
||||
guarantee(_target_occupancy > 0, "Target occupancy must be initialized");
|
||||
|
||||
if (!_is_adaptive || !have_enough_data_for_prediction()) {
|
||||
return (size_t)(_initial_ihop_percent * _target_occupancy / 100.0);
|
||||
}
|
||||
|
||||
double pred_marking_time = predict(&_marking_times_s);
|
||||
double pred_rate = predict(&_allocation_rate_s);
|
||||
size_t pred_bytes = (size_t)(pred_marking_time * pred_rate);
|
||||
size_t predicted_needed = pred_bytes + _last_unrestrained_young_size;
|
||||
size_t internal_threshold = actual_target_threshold();
|
||||
// During the time between marking start and the first Mixed GC,
|
||||
// additional memory will be consumed:
|
||||
// - Old gen grows due to allocations:
|
||||
// old_gen_alloc_bytes = old_gen_alloc_rate * marking_start_to_mixed_time
|
||||
// - Young gen will occupy a certain size at the first Mixed GC:
|
||||
// expected_young_gen_at_first_mixed_gc
|
||||
double marking_start_to_mixed_time = predict(&_marking_start_to_mixed_time_s);
|
||||
double old_gen_alloc_rate = predict(&_old_gen_alloc_rate);
|
||||
size_t old_gen_alloc_bytes = (size_t)(marking_start_to_mixed_time * old_gen_alloc_rate);
|
||||
|
||||
return predicted_needed < internal_threshold
|
||||
? internal_threshold - predicted_needed
|
||||
// Therefore, the total heap occupancy at the first Mixed GC is:
|
||||
// current_old_gen + old_gen_growth + expected_young_gen_at_first_mixed_gc
|
||||
//
|
||||
// To ensure this does not exceed the target_heap_occupancy, we work
|
||||
// backwards to compute the old gen occupancy at which marking must start:
|
||||
// mark_start_threshold = target_heap_occupancy -
|
||||
// (old_gen_growth + expected_young_gen_at_first_mixed_gc)
|
||||
|
||||
size_t predicted_needed = old_gen_alloc_bytes + _expected_young_gen_at_first_mixed_gc;
|
||||
size_t target_heap_occupancy = effective_target_occupancy();
|
||||
|
||||
return predicted_needed < target_heap_occupancy
|
||||
? target_heap_occupancy - predicted_needed
|
||||
: 0;
|
||||
}
|
||||
|
||||
void G1IHOPControl::print_log(size_t non_young_occupancy) {
|
||||
assert(_target_occupancy > 0, "Target occupancy still not updated yet.");
|
||||
size_t cur_conc_mark_start_threshold = get_conc_mark_start_threshold();
|
||||
log_debug(gc, ihop)("Basic information (value update), threshold: %zuB (%1.2f), target occupancy: %zuB, non-young occupancy: %zuB, "
|
||||
"recent allocation size: %zuB, recent allocation duration: %1.2fms, recent old gen allocation rate: %1.2fB/s, recent marking phase length: %1.2fms",
|
||||
cur_conc_mark_start_threshold,
|
||||
percent_of(cur_conc_mark_start_threshold, _target_occupancy),
|
||||
size_t old_gen_mark_start_threshold = old_gen_threshold_for_conc_mark_start();
|
||||
log_debug(gc, ihop)("Basic information (value update), old-gen threshold: %zuB (%1.2f%%), target occupancy: %zuB, old-gen occupancy: %zuB (%1.2f%%), "
|
||||
"recent old-gen allocation size: %zuB, recent allocation duration: %1.2fms, recent old-gen allocation rate: %1.2fB/s, recent marking phase length: %1.2fms",
|
||||
old_gen_mark_start_threshold,
|
||||
percent_of(old_gen_mark_start_threshold, _target_occupancy),
|
||||
_target_occupancy,
|
||||
non_young_occupancy,
|
||||
percent_of(non_young_occupancy, _target_occupancy),
|
||||
_old_gen_alloc_tracker->last_period_old_gen_bytes(),
|
||||
_last_allocation_time_s * 1000.0,
|
||||
_last_allocation_time_s > 0.0 ? _old_gen_alloc_tracker->last_period_old_gen_bytes() / _last_allocation_time_s : 0.0,
|
||||
last_marking_length_s() * 1000.0);
|
||||
last_marking_start_to_mixed_time_s() * 1000.0);
|
||||
|
||||
if (!_is_adaptive) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t actual_threshold = actual_target_threshold();
|
||||
log_debug(gc, ihop)("Adaptive IHOP information (value update), threshold: %zuB (%1.2f), internal target threshold: %zuB, "
|
||||
"non-young occupancy: %zuB, additional buffer size: %zuB, predicted old gen allocation rate: %1.2fB/s, "
|
||||
"predicted marking phase length: %1.2fms, prediction active: %s",
|
||||
cur_conc_mark_start_threshold,
|
||||
percent_of(cur_conc_mark_start_threshold, actual_threshold),
|
||||
actual_threshold,
|
||||
size_t effective_target = effective_target_occupancy();
|
||||
log_debug(gc, ihop)("Adaptive IHOP information (value update), prediction active: %s, old-gen threshold: %zuB (%1.2f%%), internal target occupancy: %zuB, "
|
||||
"old-gen occupancy: %zuB, additional buffer size: %zuB, predicted old-gen allocation rate: %1.2fB/s, "
|
||||
"predicted marking phase length: %1.2fms",
|
||||
BOOL_TO_STR(have_enough_data_for_prediction()),
|
||||
old_gen_mark_start_threshold,
|
||||
percent_of(old_gen_mark_start_threshold, effective_target),
|
||||
effective_target,
|
||||
non_young_occupancy,
|
||||
_last_unrestrained_young_size,
|
||||
predict(&_allocation_rate_s),
|
||||
predict(&_marking_times_s) * 1000.0,
|
||||
have_enough_data_for_prediction() ? "true" : "false");
|
||||
_expected_young_gen_at_first_mixed_gc,
|
||||
predict(&_old_gen_alloc_rate),
|
||||
predict(&_marking_start_to_mixed_time_s) * 1000.0);
|
||||
}
|
||||
|
||||
void G1IHOPControl::send_trace_event(G1NewTracer* tracer, size_t non_young_occupancy) {
|
||||
assert(_target_occupancy > 0, "Target occupancy still not updated yet.");
|
||||
tracer->report_basic_ihop_statistics(get_conc_mark_start_threshold(),
|
||||
tracer->report_basic_ihop_statistics(old_gen_threshold_for_conc_mark_start(),
|
||||
_target_occupancy,
|
||||
non_young_occupancy,
|
||||
_old_gen_alloc_tracker->last_period_old_gen_bytes(),
|
||||
_last_allocation_time_s,
|
||||
last_marking_length_s());
|
||||
last_marking_start_to_mixed_time_s());
|
||||
|
||||
if (_is_adaptive) {
|
||||
tracer->report_adaptive_ihop_statistics(get_conc_mark_start_threshold(),
|
||||
actual_target_threshold(),
|
||||
tracer->report_adaptive_ihop_statistics(old_gen_threshold_for_conc_mark_start(),
|
||||
effective_target_occupancy(),
|
||||
non_young_occupancy,
|
||||
_last_unrestrained_young_size,
|
||||
predict(&_allocation_rate_s),
|
||||
predict(&_marking_times_s),
|
||||
_expected_young_gen_at_first_mixed_gc,
|
||||
predict(&_old_gen_alloc_rate),
|
||||
predict(&_marking_start_to_mixed_time_s),
|
||||
have_enough_data_for_prediction());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2026, 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
|
||||
@ -58,8 +58,11 @@ class G1IHOPControl : public CHeapObj<mtGC> {
|
||||
const G1OldGenAllocationTracker* _old_gen_alloc_tracker;
|
||||
|
||||
const G1Predictions* _predictor;
|
||||
TruncatedSeq _marking_times_s;
|
||||
TruncatedSeq _allocation_rate_s;
|
||||
// Wall-clock time in seconds from marking start to the first mixed GC,
|
||||
// excluding GC Pause time.
|
||||
TruncatedSeq _marking_start_to_mixed_time_s;
|
||||
// Old generation allocation rate in bytes per second.
|
||||
TruncatedSeq _old_gen_alloc_rate;
|
||||
|
||||
// The most recent unrestrained size of the young gen. This is used as an additional
|
||||
// factor in the calculation of the threshold, as the threshold is based on
|
||||
@ -68,18 +71,18 @@ class G1IHOPControl : public CHeapObj<mtGC> {
|
||||
// Since we cannot know what young gen sizes are used in the future, we will just
|
||||
// use the current one. We expect that this one will be one with a fairly large size,
|
||||
// as there is no marking or mixed gc that could impact its size too much.
|
||||
size_t _last_unrestrained_young_size;
|
||||
size_t _expected_young_gen_at_first_mixed_gc;
|
||||
|
||||
// Get a new prediction bounded below by zero from the given sequence.
|
||||
double predict(const TruncatedSeq* seq) const;
|
||||
|
||||
bool have_enough_data_for_prediction() const;
|
||||
double last_marking_length_s() const;
|
||||
double last_marking_start_to_mixed_time_s() const;
|
||||
|
||||
// The "actual" target threshold the algorithm wants to keep during and at the
|
||||
// end of marking. This is typically lower than the requested threshold, as the
|
||||
// The "effective" target occupancy the algorithm wants to keep until the start
|
||||
// of Mixed GCs. This is typically lower than the target occupancy, as the
|
||||
// algorithm needs to consider restrictions by the environment.
|
||||
size_t actual_target_threshold() const;
|
||||
size_t effective_target_occupancy() const;
|
||||
|
||||
void print_log(size_t non_young_occupancy);
|
||||
void send_trace_event(G1NewTracer* tracer, size_t non_young_occupancy);
|
||||
@ -95,22 +98,24 @@ class G1IHOPControl : public CHeapObj<mtGC> {
|
||||
// Adjust target occupancy.
|
||||
void update_target_occupancy(size_t new_target_occupancy);
|
||||
|
||||
// Update information about time during which allocations in the Java heap occurred,
|
||||
// how large these allocations were in bytes, and an additional buffer.
|
||||
// The allocations should contain any amount of space made unusable for further
|
||||
// allocation, e.g. any waste caused by TLAB allocation, space at the end of
|
||||
// humongous objects that can not be used for allocation, etc.
|
||||
// Together with the target occupancy, this additional buffer should contain the
|
||||
// difference between old gen size and total heap size at the start of reclamation,
|
||||
// and space required for that reclamation.
|
||||
void update_allocation_info(double allocation_time_s, size_t additional_buffer_size);
|
||||
void update_target_after_marking_phase();
|
||||
|
||||
// Update allocation rate information and current expected young gen size for the
|
||||
// first mixed gc needed for the predictor. Allocation rate is given as the
|
||||
// separately passed in allocation increment and the time passed (mutator time)
|
||||
// for the latest allocation increment here. Allocation size is the memory needed
|
||||
// during the mutator before and the first mixed gc pause itself.
|
||||
// Contents include young gen at that point, and the memory required for evacuating
|
||||
// the collection set in that first mixed gc (including waste caused by PLAB
|
||||
// allocation etc.).
|
||||
void update_allocation_info(double allocation_time_s, size_t expected_young_gen_size);
|
||||
|
||||
// Update the time spent in the mutator beginning from the end of concurrent start to
|
||||
// the first mixed gc.
|
||||
void update_marking_length(double marking_length_s);
|
||||
void add_marking_start_to_mixed_length(double length_s);
|
||||
|
||||
// Get the current non-young occupancy at which concurrent marking should start.
|
||||
size_t get_conc_mark_start_threshold();
|
||||
size_t old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
void report_statistics(G1NewTracer* tracer, size_t non_young_occupancy);
|
||||
};
|
||||
|
||||
@ -738,15 +738,15 @@ bool G1Policy::need_to_start_conc_mark(const char* source, size_t allocation_wor
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t marking_initiating_used_threshold = _ihop_control->get_conc_mark_start_threshold();
|
||||
size_t marking_initiating_old_gen_threshold = _ihop_control->old_gen_threshold_for_conc_mark_start();
|
||||
size_t non_young_occupancy = _g1h->non_young_occupancy_after_allocation(allocation_word_size);
|
||||
|
||||
bool result = false;
|
||||
if (non_young_occupancy > marking_initiating_used_threshold) {
|
||||
if (non_young_occupancy > marking_initiating_old_gen_threshold) {
|
||||
result = collector_state()->is_in_young_only_phase();
|
||||
log_debug(gc, ergo, ihop)("%s non-young occupancy: %zuB allocation request: %zuB threshold: %zuB (%1.2f) source: %s",
|
||||
result ? "Request concurrent cycle initiation (occupancy higher than threshold)" : "Do not request concurrent cycle initiation (still doing mixed collections)",
|
||||
non_young_occupancy, allocation_word_size * HeapWordSize, marking_initiating_used_threshold, (double) marking_initiating_used_threshold / _g1h->capacity() * 100, source);
|
||||
non_young_occupancy, allocation_word_size * HeapWordSize, marking_initiating_old_gen_threshold, (double) marking_initiating_old_gen_threshold / _g1h->capacity() * 100, source);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -972,8 +972,7 @@ void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mar
|
||||
update_young_length_bounds();
|
||||
|
||||
_old_gen_alloc_tracker.reset_after_gc(_g1h->humongous_regions_count() * G1HeapRegion::GrainBytes);
|
||||
if (update_ihop_prediction(app_time_ms / 1000.0,
|
||||
G1CollectorState::is_young_only_pause(this_pause))) {
|
||||
if (update_ihop_prediction(app_time_ms / 1000.0, is_young_only_pause)) {
|
||||
_ihop_control->report_statistics(_g1h->gc_tracer_stw(), _g1h->non_young_occupancy_after_allocation(allocation_word_size));
|
||||
}
|
||||
} else {
|
||||
@ -1030,14 +1029,13 @@ bool G1Policy::update_ihop_prediction(double mutator_time_s,
|
||||
|
||||
bool report = false;
|
||||
|
||||
double marking_to_mixed_time = -1.0;
|
||||
if (!this_gc_was_young_only && _concurrent_start_to_mixed.has_result()) {
|
||||
marking_to_mixed_time = _concurrent_start_to_mixed.last_marking_time();
|
||||
double marking_to_mixed_time = _concurrent_start_to_mixed.get_and_reset_last_marking_time();
|
||||
assert(marking_to_mixed_time > 0.0,
|
||||
"Concurrent start to mixed time must be larger than zero but is %.3f",
|
||||
marking_to_mixed_time);
|
||||
if (marking_to_mixed_time > min_valid_time) {
|
||||
_ihop_control->update_marking_length(marking_to_mixed_time);
|
||||
_ihop_control->add_marking_start_to_mixed_length(marking_to_mixed_time);
|
||||
report = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2026, 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
|
||||
@ -40,7 +40,7 @@ static void test_update(G1IHOPControl* ctrl,
|
||||
test_update_allocation_tracker(alloc_tracker, alloc_amount);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ctrl->update_allocation_info(alloc_time, young_size);
|
||||
ctrl->update_marking_length(mark_time);
|
||||
ctrl->add_marking_start_to_mixed_length(mark_time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ static void test_update_humongous(G1IHOPControl* ctrl,
|
||||
alloc_tracker->reset_after_gc(humongous_bytes_after_last_gc);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ctrl->update_allocation_info(alloc_time, young_size);
|
||||
ctrl->update_marking_length(mark_time);
|
||||
ctrl->add_marking_start_to_mixed_length(mark_time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,26 +74,26 @@ TEST_VM(G1IHOPControl, static_simple) {
|
||||
G1IHOPControl ctrl(initial_ihop, &alloc_tracker, is_adaptive, nullptr, 0, 0);
|
||||
ctrl.update_target_occupancy(100);
|
||||
|
||||
size_t threshold = ctrl.get_conc_mark_start_threshold();
|
||||
size_t threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
EXPECT_EQ(initial_ihop, threshold);
|
||||
|
||||
test_update_allocation_tracker(&alloc_tracker, 100);
|
||||
ctrl.update_allocation_info(100.0, 100);
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
EXPECT_EQ(initial_ihop, threshold);
|
||||
|
||||
ctrl.update_marking_length(1000.0);
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
ctrl.add_marking_start_to_mixed_length(1000.0);
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
EXPECT_EQ(initial_ihop, threshold);
|
||||
|
||||
// Whatever we pass, the IHOP value must stay the same.
|
||||
test_update(&ctrl, &alloc_tracker, 2, 10, 10, 3);
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
EXPECT_EQ(initial_ihop, threshold);
|
||||
|
||||
test_update(&ctrl, &alloc_tracker, 12, 10, 10, 3);
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
EXPECT_EQ(initial_ihop, threshold);
|
||||
}
|
||||
@ -126,23 +126,23 @@ TEST_VM(G1IHOPControl, adaptive_simple) {
|
||||
- (young_size + alloc_amount1 / alloc_time1 * marking_time1);
|
||||
|
||||
size_t threshold;
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
EXPECT_EQ(initial_threshold, threshold);
|
||||
|
||||
for (size_t i = 0; i < G1AdaptiveIHOPNumInitialSamples - 1; i++) {
|
||||
test_update_allocation_tracker(&alloc_tracker, alloc_amount1);
|
||||
ctrl.update_allocation_info(alloc_time1, young_size);
|
||||
ctrl.update_marking_length(marking_time1);
|
||||
ctrl.add_marking_start_to_mixed_length(marking_time1);
|
||||
// Not enough data yet.
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
ASSERT_EQ(initial_threshold, threshold) << "on step " << i;
|
||||
}
|
||||
|
||||
test_update(&ctrl, &alloc_tracker, alloc_time1, alloc_amount1, young_size, marking_time1);
|
||||
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
EXPECT_EQ(settled_ihop1, threshold);
|
||||
|
||||
@ -155,7 +155,7 @@ TEST_VM(G1IHOPControl, adaptive_simple) {
|
||||
|
||||
test_update(&ctrl, &alloc_tracker, alloc_time2, alloc_amount2, young_size, marking_time2);
|
||||
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
EXPECT_LT(threshold, settled_ihop1);
|
||||
|
||||
@ -166,14 +166,14 @@ TEST_VM(G1IHOPControl, adaptive_simple) {
|
||||
const size_t settled_ihop3 = 0;
|
||||
|
||||
test_update(&ctrl, &alloc_tracker, alloc_time3, alloc_amount3, young_size, marking_time3);
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
EXPECT_EQ(settled_ihop3, threshold);
|
||||
|
||||
// And back to some arbitrary value.
|
||||
test_update(&ctrl, &alloc_tracker, alloc_time2, alloc_amount2, young_size, marking_time2);
|
||||
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
|
||||
EXPECT_GT(threshold, settled_ihop3);
|
||||
}
|
||||
@ -205,7 +205,7 @@ TEST_VM(G1IHOPControl, adaptive_humongous) {
|
||||
humongous_bytes_after_last_gc, young_size, marking_time);
|
||||
// Test threshold
|
||||
size_t threshold;
|
||||
threshold = ctrl.get_conc_mark_start_threshold();
|
||||
threshold = ctrl.old_gen_threshold_for_conc_mark_start();
|
||||
// Adjusted allocated bytes:
|
||||
// Total bytes: humongous_bytes
|
||||
// Freed hum bytes: humongous_bytes - humongous_bytes_after_last_gc
|
||||
@ -219,7 +219,7 @@ TEST_VM(G1IHOPControl, adaptive_humongous) {
|
||||
ctrl2.update_target_occupancy(target_size);
|
||||
test_update_humongous(&ctrl2, &alloc_tracker, duration, old_bytes, humongous_bytes,
|
||||
humongous_bytes_after_gc, young_size, marking_time);
|
||||
threshold = ctrl2.get_conc_mark_start_threshold();
|
||||
threshold = ctrl2.old_gen_threshold_for_conc_mark_start();
|
||||
// Adjusted allocated bytes:
|
||||
// Total bytes: old_bytes + humongous_bytes
|
||||
// Freed hum bytes: humongous_bytes - (humongous_bytes_after_gc - humongous_bytes_after_last_gc)
|
||||
@ -235,7 +235,7 @@ TEST_VM(G1IHOPControl, adaptive_humongous) {
|
||||
ctrl3.update_target_occupancy(target_size);
|
||||
test_update_humongous(&ctrl3, &alloc_tracker, duration, old_bytes, humongous_bytes,
|
||||
humongous_bytes_after_gc, young_size, marking_time);
|
||||
threshold = ctrl3.get_conc_mark_start_threshold();
|
||||
threshold = ctrl3.old_gen_threshold_for_conc_mark_start();
|
||||
// Adjusted allocated bytes:
|
||||
// All humongous are cleaned up since humongous_bytes_after_gc < humongous_bytes_after_last_gc
|
||||
// Total bytes: old_bytes + humongous_bytes
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user