Skip to content

Commit

Permalink
8311602: GenShen: Decouple generational mode heuristics
Browse files Browse the repository at this point in the history
Reviewed-by: kdnilsen, ysr
  • Loading branch information
William Kemper committed Jul 20, 2023
1 parent 0fbfe19 commit 09f6c03
Show file tree
Hide file tree
Showing 40 changed files with 1,384 additions and 987 deletions.

Large diffs are not rendered by default.

Expand Up @@ -26,6 +26,10 @@
#ifndef SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHADAPTIVEHEURISTICS_HPP
#define SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHADAPTIVEHEURISTICS_HPP

#include "runtime/globals_extension.hpp"
#include "memory/allocation.hpp"
#include "gc/shenandoah/heuristics/shenandoahHeapStats.hpp"
#include "gc/shenandoah/shenandoahSharedVariables.hpp"
#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
#include "gc/shenandoah/shenandoahPhaseTimings.hpp"
#include "utilities/numberSeq.hpp"
Expand All @@ -52,7 +56,7 @@ class ShenandoahAllocationRate : public CHeapObj<mtGC> {

class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics {
public:
ShenandoahAdaptiveHeuristics(ShenandoahGeneration* generation);
ShenandoahAdaptiveHeuristics(ShenandoahHeapStats* heap_stats);

virtual ~ShenandoahAdaptiveHeuristics();

Expand All @@ -71,8 +75,6 @@ class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics {
virtual bool is_diagnostic() { return false; }
virtual bool is_experimental() { return false; }

virtual size_t bytes_of_allocation_runway_before_gc_trigger(size_t young_regions_to_be_recycled);

private:
// These are used to adjust the margin of error and the spike threshold
// in response to GC cycle outcomes. These values are shared, but the
Expand Down Expand Up @@ -100,11 +102,14 @@ class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics {
void adjust_margin_of_error(double amount);
void adjust_spike_threshold(double amount);

protected:
ShenandoahHeapStats* _heap_stats;

ShenandoahAllocationRate _allocation_rate;

// The margin of error expressed in standard deviations to add to our
// average cycle time and allocation rate. As this value increases we
// tend to over estimate the rate at which mutators will deplete the
// tend to overestimate the rate at which mutators will deplete the
// heap. In other words, erring on the side of caution will trigger more
// concurrent GCs.
double _margin_of_error_sd;
Expand All @@ -127,6 +132,8 @@ class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics {
// establishes what is 'normal' for the application and is used as a
// source of feedback to adjust trigger parameters.
TruncatedSeq _available;

size_t min_free_threshold();
};

#endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHADAPTIVEHEURISTICS_HPP
Expand Up @@ -32,12 +32,7 @@
#include "logging/logTag.hpp"
#include "runtime/os.hpp"

ShenandoahAggressiveHeuristics::ShenandoahAggressiveHeuristics(ShenandoahGeneration* generation) :
ShenandoahHeuristics(generation) {

assert(!ShenandoahHeap::heap()->mode()->is_generational(),
"Aggressive heuristics is not available in generational mode");

ShenandoahAggressiveHeuristics::ShenandoahAggressiveHeuristics() : ShenandoahHeuristics() {
// Do not shortcut evacuation
SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahImmediateThreshold, 100);

Expand All @@ -54,8 +49,6 @@ ShenandoahAggressiveHeuristics::ShenandoahAggressiveHeuristics(ShenandoahGenerat
void ShenandoahAggressiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
RegionData* data, size_t size,
size_t free) {
// Note that there is no bound on collection set size. If we try to collect too much memory,
// we'll get an allocation failure during collection and slide to degenerated GC.
for (size_t idx = 0; idx < size; idx++) {
ShenandoahHeapRegion* r = data[idx]._region;
if (r->garbage() > 0) {
Expand Down
Expand Up @@ -30,7 +30,7 @@

class ShenandoahAggressiveHeuristics : public ShenandoahHeuristics {
public:
ShenandoahAggressiveHeuristics(ShenandoahGeneration* generation);
ShenandoahAggressiveHeuristics();

virtual void choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset,
RegionData* data, size_t size,
Expand Down
Expand Up @@ -28,13 +28,12 @@
#include "gc/shenandoah/shenandoahCollectionSet.hpp"
#include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp"
#include "gc/shenandoah/shenandoahFreeSet.hpp"
#include "gc/shenandoah/shenandoahGeneration.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
#include "logging/log.hpp"
#include "logging/logTag.hpp"

ShenandoahCompactHeuristics::ShenandoahCompactHeuristics(ShenandoahGeneration* generation) :
ShenandoahHeuristics(generation) {
ShenandoahCompactHeuristics::ShenandoahCompactHeuristics() : ShenandoahHeuristics() {
SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent);
SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent);
SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahUncommit);
Expand All @@ -47,17 +46,18 @@ ShenandoahCompactHeuristics::ShenandoahCompactHeuristics(ShenandoahGeneration* g
}

bool ShenandoahCompactHeuristics::should_start_gc() {
size_t max_capacity = _generation->max_capacity();
size_t capacity = _generation->soft_max_capacity();
size_t usage = _generation->used();
size_t available = (capacity > usage)? capacity - usage: 0;
ShenandoahHeap* heap = ShenandoahHeap::heap();

size_t max_capacity = heap->max_capacity();
size_t capacity = heap->soft_max_capacity();
size_t available = heap->free_set()->available();

// Make sure the code below treats available without the soft tail.
size_t soft_tail = max_capacity - capacity;
available = (available > soft_tail) ? (available - soft_tail) : 0;

size_t threshold_bytes_allocated = capacity / 100 * ShenandoahAllocationThreshold;
size_t min_threshold = min_free_threshold();
size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;

if (available < min_threshold) {
log_info(gc)("Trigger: Free (" SIZE_FORMAT "%s) is below minimum threshold (" SIZE_FORMAT "%s)",
Expand All @@ -66,7 +66,7 @@ bool ShenandoahCompactHeuristics::should_start_gc() {
return true;
}

size_t bytes_allocated = _generation->bytes_allocated_since_gc_start();
size_t bytes_allocated = heap->bytes_allocated_since_gc_start();
if (bytes_allocated > threshold_bytes_allocated) {
log_info(gc)("Trigger: Allocated since last cycle (" SIZE_FORMAT "%s) is larger than allocation threshold (" SIZE_FORMAT "%s)",
byte_size_in_proper_unit(bytes_allocated), proper_unit_for_byte_size(bytes_allocated),
Expand Down
Expand Up @@ -29,7 +29,7 @@

class ShenandoahCompactHeuristics : public ShenandoahHeuristics {
public:
ShenandoahCompactHeuristics(ShenandoahGeneration* generation);
ShenandoahCompactHeuristics();

virtual bool should_start_gc();

Expand Down

0 comments on commit 09f6c03

Please sign in to comment.