Skip to content

Commit

Permalink
8318190: GenShen: Be less aggressive with triggers for old-gen has ex…
Browse files Browse the repository at this point in the history
…panded

Reviewed-by: wkemper
  • Loading branch information
kdnilsen committed Oct 18, 2023
1 parent e2821e4 commit ac30d48
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp"
#include "gc/shenandoah/shenandoahCollectionSet.hpp"
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
#include "gc/shenandoah/shenandoahOldGeneration.hpp"
Expand Down Expand Up @@ -502,8 +503,8 @@ bool ShenandoahOldHeuristics::should_start_gc() {
return true;
}

ShenandoahHeap* heap = ShenandoahHeap::heap();
if (_fragmentation_trigger) {
ShenandoahHeap* heap = ShenandoahHeap::heap();
size_t used = _old_generation->used();
size_t used_regions_size = _old_generation->used_regions_size();
size_t used_regions = _old_generation->used_regions();
Expand All @@ -519,10 +520,21 @@ bool ShenandoahOldHeuristics::should_start_gc() {
if (_growth_trigger) {
// Growth may be falsely triggered during mixed evacuations, before the mixed-evacuation candidates have been
// evacuated. Before acting on a false trigger, we check to confirm the trigger condition is still satisfied.
ShenandoahHeap* heap = ShenandoahHeap::heap();
size_t current_usage = _old_generation->used();
size_t trigger_threshold = _old_generation->usage_trigger_threshold();
if (current_usage > trigger_threshold) {
size_t heap_size = heap->capacity();
size_t consecutive_young_cycles;
if ((current_usage < ShenandoahIgnoreOldGrowthBelowPercentage * heap_size / 100) &&
((consecutive_young_cycles = heap->shenandoah_policy()->consecutive_young_gc_count())
< ShenandoahDoNotIgnoreGrowthAfterYoungCycles)) {
log_info(gc)("Ignoring Trigger (OLD): Old has overgrown: usage (" SIZE_FORMAT "%s) is below threshold (" SIZE_FORMAT
"%s) after " SIZE_FORMAT " consecutive completed young GCs",
byte_size_in_proper_unit(current_usage), proper_unit_for_byte_size(current_usage),
byte_size_in_proper_unit(ShenandoahDoNotIgnoreGrowthAfterYoungCycles),
proper_unit_for_byte_size(ShenandoahDoNotIgnoreGrowthAfterYoungCycles),
consecutive_young_cycles);
_growth_trigger = false;
} else if (current_usage > trigger_threshold) {
size_t live_at_previous_old = _old_generation->get_live_bytes_after_last_mark();
double percent_growth = percent_of(current_usage - live_at_previous_old, live_at_previous_old);
log_info(gc)("Trigger (OLD): Old has overgrown, live at end of previous OLD marking: "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ class ShenandoahYoungHeuristics : public ShenandoahGenerationalHeuristics {

};

#endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHYOUNGHEURISTICS_HPP
#endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHYOUNGHEURISTICS_HPP
18 changes: 16 additions & 2 deletions src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ ShenandoahCollectorPolicy::ShenandoahCollectorPolicy() :
_interrupted_old_gcs(0),
_success_degenerated_gcs(0),
_success_full_gcs(0),
_consecutive_young_gcs(0),
_alloc_failure_degenerated(0),
_alloc_failure_degenerated_upgrade_to_full(0),
_alloc_failure_full(0),
Expand Down Expand Up @@ -84,7 +85,12 @@ void ShenandoahCollectorPolicy::record_degenerated_upgrade_to_full() {
_alloc_failure_degenerated_upgrade_to_full++;
}

void ShenandoahCollectorPolicy::record_success_concurrent() {
void ShenandoahCollectorPolicy::record_success_concurrent(bool is_young) {
if (is_young) {
_consecutive_young_gcs++;
} else {
_consecutive_young_gcs = 0;
}
_success_concurrent_gcs++;
}

Expand All @@ -97,18 +103,26 @@ void ShenandoahCollectorPolicy::record_abbreviated_cycle() {
}

void ShenandoahCollectorPolicy::record_success_old() {
_consecutive_young_gcs = 0;
_success_old_gcs++;
}

void ShenandoahCollectorPolicy::record_interrupted_old() {
_consecutive_young_gcs = 0;
_interrupted_old_gcs++;
}

void ShenandoahCollectorPolicy::record_success_degenerated() {
void ShenandoahCollectorPolicy::record_success_degenerated(bool is_young) {
if (is_young) {
_consecutive_young_gcs++;
} else {
_consecutive_young_gcs = 0;
}
_success_degenerated_gcs++;
}

void ShenandoahCollectorPolicy::record_success_full() {
_consecutive_young_gcs = 0;
_success_full_gcs++;
}

Expand Down
9 changes: 7 additions & 2 deletions src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class ShenandoahCollectorPolicy : public CHeapObj<mtGC> {
size_t _success_degenerated_gcs;
// Written by control thread, read by mutators
volatile size_t _success_full_gcs;
volatile size_t _consecutive_young_gcs;
size_t _alloc_failure_degenerated;
size_t _alloc_failure_degenerated_upgrade_to_full;
size_t _alloc_failure_full;
Expand All @@ -69,10 +70,10 @@ class ShenandoahCollectorPolicy : public CHeapObj<mtGC> {

void record_mixed_cycle();
void record_abbreviated_cycle();
void record_success_concurrent();
void record_success_concurrent(bool is_young);
void record_success_old();
void record_interrupted_old();
void record_success_degenerated();
void record_success_degenerated(bool is_young);
void record_success_full();
void record_alloc_failure_to_degenerated(ShenandoahGC::ShenandoahDegenPoint point);
void record_alloc_failure_to_full();
Expand All @@ -94,6 +95,10 @@ class ShenandoahCollectorPolicy : public CHeapObj<mtGC> {
size_t full_gc_count() const {
return _success_full_gcs + _alloc_failure_degenerated_upgrade_to_full;
}

inline size_t consecutive_young_gc_count() const {
return _consecutive_young_gcs;
}
};

#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCOLLECTORPOLICY_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ bool ShenandoahControlThread::service_stw_degenerated_cycle(GCCause::Cause cause
}

_degen_generation->heuristics()->record_success_degenerated();
heap->shenandoah_policy()->record_success_degenerated();
heap->shenandoah_policy()->record_success_degenerated(_degen_generation->is_young());
return !gc.upgraded_to_full();
}

Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1016,10 +1016,10 @@ void ShenandoahGeneration::decrease_capacity(size_t decrement) {

void ShenandoahGeneration::record_success_concurrent(bool abbreviated) {
heuristics()->record_success_concurrent(abbreviated);
ShenandoahHeap::heap()->shenandoah_policy()->record_success_concurrent();
ShenandoahHeap::heap()->shenandoah_policy()->record_success_concurrent(is_young());
}

void ShenandoahGeneration::record_success_degenerated() {
heuristics()->record_success_degenerated();
ShenandoahHeap::heap()->shenandoah_policy()->record_success_degenerated();
ShenandoahHeap::heap()->shenandoah_policy()->record_success_degenerated(is_young());
}
8 changes: 5 additions & 3 deletions src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ ShenandoahOldGeneration::ShenandoahOldGeneration(uint max_queues, size_t max_cap
: ShenandoahGeneration(OLD, max_queues, max_capacity, soft_max_capacity),
_coalesce_and_fill_region_array(NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, ShenandoahHeap::heap()->num_regions(), mtGC)),
_state(IDLE),
_growth_before_compaction(INITIAL_GROWTH_BEFORE_COMPACTION)
_growth_before_compaction(INITIAL_GROWTH_BEFORE_COMPACTION),
_min_growth_before_compaction ((ShenandoahMinOldGenGrowthPercent * FRACTIONAL_DENOMINATOR) / 100)
{
_live_bytes_after_last_mark = ShenandoahHeap::heap()->capacity() * INITIAL_LIVE_FRACTION / FRACTIONAL_DENOMINATOR;
// Always clear references for old generation
Expand All @@ -188,8 +189,9 @@ size_t ShenandoahOldGeneration::get_live_bytes_after_last_mark() const {

void ShenandoahOldGeneration::set_live_bytes_after_last_mark(size_t bytes) {
_live_bytes_after_last_mark = bytes;
if (_growth_before_compaction > MINIMUM_GROWTH_BEFORE_COMPACTION) {
_growth_before_compaction /= 2;
_growth_before_compaction /= 2;
if (_growth_before_compaction < _min_growth_before_compaction) {
_growth_before_compaction = _min_growth_before_compaction;
}
}

Expand Down
17 changes: 10 additions & 7 deletions src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,20 @@ class ShenandoahOldGeneration : public ShenandoahGeneration {
// memory at the end of the first old-gen collection. Then we trigger again when old-gen growns 12.5%
// more than its live memory at the end of the previous old-gen collection. Thereafter, we trigger each time
// old-gen grows more than 12.5% following the end of its previous old-gen collection.
static const size_t INITIAL_GROWTH_BEFORE_COMPACTION = FRACTIONAL_DENOMINATOR / 2; // 50.0%
static const size_t MINIMUM_GROWTH_BEFORE_COMPACTION = FRACTIONAL_DENOMINATOR / 8; // 12.5%
static const size_t INITIAL_GROWTH_BEFORE_COMPACTION = FRACTIONAL_DENOMINATOR / 2; // 50.0%

// INITIAL_LIVE_FRACTION represents the initial guess of how large old-gen should be. We estimate that old-gen
// needs to consume 3.125% of the total heap size. And we "pretend" that we start out with this amount of live
// needs to consume 6.25% of the total heap size. And we "pretend" that we start out with this amount of live
// old-gen memory. The first old-collection trigger will occur when old-gen occupies 50% more than this initial
// approximation of the old-gen memory requirement, in other words when old-gen usage is 150% of 3.125%, which
// is 4.6875% of the total heap size.
static const uint16_t INITIAL_LIVE_FRACTION = FRACTIONAL_DENOMINATOR / 32; // 3.125%
// approximation of the old-gen memory requirement, in other words when old-gen usage is 150% of 6.25%, which
// is 9.375% of the total heap size.
static const uint16_t INITIAL_LIVE_FRACTION = FRACTIONAL_DENOMINATOR / 16; // 6.25%

size_t _live_bytes_after_last_mark;
size_t _growth_before_compaction; // How much growth in usage before we trigger old collection, per 65_536

// How much growth in usage before we trigger old collection, per FRACTIONAL_DENOMINATOR (65_536)
size_t _growth_before_compaction;
const size_t _min_growth_before_compaction; // Default is 12.5%

void validate_transition(State new_state) NOT_DEBUG_RETURN;

Expand Down
25 changes: 25 additions & 0 deletions src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,31 @@
range, \
constraint) \
\
product(double, ShenandoahMinOldGenGrowthPercent,12.5, EXPERIMENTAL, \
"(Generational mode only) If the usage within old generation " \
"has grown by at least this percent of its live memory size " \
"at completion of the most recent old-generation marking " \
"effort, heuristics may trigger the start of a new old-gen " \
"collection.") \
range(0.0,100.0) \
\
product(uintx, ShenandoahIgnoreOldGrowthBelowPercentage,10, EXPERIMENTAL, \
"(Generational mode only) If the total usage of the old " \
"generation is smaller than this percent, we do not trigger " \
"old gen collections even if old has grown, except when " \
"ShenandoahGenerationalDoNotIgnoreGrowthAfterYoungCycles " \
"consecutive cycles have been completed following the " \
"preceding old-gen collection.") \
range(0,100) \
\
product(uintx, ShenandoahDoNotIgnoreGrowthAfterYoungCycles, \
50, EXPERIMENTAL, \
"(Generational mode only) Even if the usage of old generation " \
"is below ShenandoahIgnoreOldGrowthBelowPercentage, " \
"trigger an old-generation mark if old has grown and this " \
"many consecutive young-gen collections have been " \
"completed following the preceding old-gen collection.") \
\
product(bool, ShenandoahGenerationalCensusAtEvac, false, EXPERIMENTAL, \
"(Generational mode only) Object age census at evacuation, " \
"rather than during marking.") \
Expand Down

0 comments on commit ac30d48

Please sign in to comment.