From 4eb67734b782cc2eac66736bb1f723f46308cecf Mon Sep 17 00:00:00 2001 From: William Kemper Date: Thu, 28 May 2026 17:56:45 +0000 Subject: [PATCH] 8385430: Shenandoah: Compact heuristic runs continuously when allocation is idle Reviewed-by: shade, kdnilsen --- .../shenandoahCompactHeuristics.cpp | 19 +++++++++---------- .../shenandoahCompactHeuristics.hpp | 4 +++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp index 4f5a750a1bf..26a2363d4d5 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp @@ -32,7 +32,8 @@ #include "logging/logTag.hpp" ShenandoahCompactHeuristics::ShenandoahCompactHeuristics(ShenandoahSpaceInfo* space_info) : - ShenandoahHeuristics(space_info) { + ShenandoahHeuristics(space_info), + _bytes_used_at_end_of_gc(0) { SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahUncommit); @@ -46,9 +47,10 @@ ShenandoahCompactHeuristics::ShenandoahCompactHeuristics(ShenandoahSpaceInfo* sp } bool ShenandoahCompactHeuristics::should_start_gc() { + const size_t used = _space_info->used(); const size_t capacity = ShenandoahHeap::heap()->soft_max_capacity(); const size_t available = _space_info->soft_mutator_available(); - const size_t bytes_allocated = estimate_bytes_allocated_since_gc_start(); + const size_t bytes_allocated = used > _bytes_used_at_end_of_gc ? used - _bytes_used_at_end_of_gc : 0; log_debug(gc, ergo)("should_start_gc calculation: available: " PROPERFMT ", soft_max_capacity: " PROPERFMT ", " "allocated_since_gc_start: " PROPERFMT, @@ -74,6 +76,11 @@ bool ShenandoahCompactHeuristics::should_start_gc() { return ShenandoahHeuristics::should_start_gc(); } +void ShenandoahCompactHeuristics::record_cycle_end() { + ShenandoahHeuristics::record_cycle_end(); + _bytes_used_at_end_of_gc = _space_info->used(); +} + void ShenandoahCompactHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, RegionData* data, size_t size, size_t actual_free) { @@ -94,11 +101,3 @@ void ShenandoahCompactHeuristics::choose_collection_set_from_regiondata(Shenando } } } - -size_t ShenandoahCompactHeuristics::estimate_bytes_allocated_since_gc_start() const { - ShenandoahHeap* heap = ShenandoahHeap::heap(); - const double average_allocation_rate = heap->alloc_rate().weighted_average(); - const double now = os::elapsedTime(); - const double elapsed_seconds = now - cycle_start_time_seconds(); - return shenandoah_safe_size_cast(average_allocation_rate * elapsed_seconds); -} diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp index 55d62d2f707..3670cdec9f0 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp @@ -41,13 +41,15 @@ public: bool is_diagnostic() override { return false; } bool is_experimental() override { return false; } + void record_cycle_end() override; + protected: void choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, RegionData* data, size_t size, size_t actual_free) override; private: - size_t estimate_bytes_allocated_since_gc_start() const; + size_t _bytes_used_at_end_of_gc; }; #endif // SHARE_GC_SHENANDOAH_HEURISTICS_SHENANDOAHCOMPACTHEURISTICS_HPP