8368681: Shenandoah: Add documentation comments for ShenandoahAllocationRate

Reviewed-by: wkemper, xpeng
This commit is contained in:
Kelvin Nilsen 2025-10-17 17:17:03 +00:00
parent f84be36dd5
commit a3e41ea6c6
2 changed files with 44 additions and 0 deletions

View File

@ -32,25 +32,62 @@
#include "memory/allocation.hpp"
#include "utilities/numberSeq.hpp"
/**
* ShenanoahAllocationRate maintains a truncated history of recently sampled allocation rates for the purpose of providing
* informed estimates of current and future allocation rates based on weighted averages and standard deviations of the
* truncated history. More recently sampled allocations are weighted more heavily than older samples when computing
* averages and standard deviations.
*/
class ShenandoahAllocationRate : public CHeapObj<mtGC> {
public:
explicit ShenandoahAllocationRate();
// Reset the _last_sample_value to zero, _last_sample_time to current time.
void allocation_counter_reset();
// Force an allocation rate sample to be taken, even if the time since last sample is not greater than
// 1s/ShenandoahAdaptiveSampleFrequencyHz, except when current_time - _last_sample_time < MinSampleTime (2 ms).
// The sampled allocation rate is computed from (allocated - _last_sample_value) / (current_time - _last_sample_time).
// Return the newly computed rate if the sample is taken, zero if it is not an appropriate time to add a sample.
// In the case that a new sample is not taken, overwrite unaccounted_bytes_allocated with bytes allocated since
// the previous sample was taken (allocated - _last_sample_value). Otherwise, overwrite unaccounted_bytes_allocated
// with 0.
double force_sample(size_t allocated, size_t &unaccounted_bytes_allocated);
// Add an allocation rate sample if the time since last sample is greater than 1s/ShenandoahAdaptiveSampleFrequencyHz.
// The sampled allocation rate is computed from (allocated - _last_sample_value) / (current_time - _last_sample_time).
// Return the newly computed rate if the sample is taken, zero if it is not an appropriate time to add a sample.
double sample(size_t allocated);
// Return an estimate of the upper bound on allocation rate, with the upper bound computed as the weighted average
// of recently sampled instantaneous allocation rates added to sds times the standard deviation computed for the
// sequence of recently sampled average allocation rates.
double upper_bound(double sds) const;
// Test whether rate significantly diverges from the computed average allocation rate. If so, return true.
// Otherwise, return false. Significant divergence is recognized if (rate - _rate.avg()) / _rate.sd() > threshold.
bool is_spiking(double rate, double threshold) const;
private:
// Return the instantaneous rate calculated from (allocated - _last_sample_value) / (time - _last_sample_time).
// Return Sentinel value 0.0 if (time - _last_sample_time) == 0 or if (allocated <= _last_sample_value).
double instantaneous_rate(double time, size_t allocated) const;
// Time at which previous allocation rate sample was collected.
double _last_sample_time;
// Bytes allocated as of the time at which previous allocation rate sample was collected.
size_t _last_sample_value;
// The desired interval of time between consecutive samples of the allocation rate.
double _interval_sec;
// Holds a sequence of the most recently sampled instantaneous allocation rates
TruncatedSeq _rate;
// Holds a sequence of the most recently computed weighted average of allocation rates, with each weighted average
// computed immediately after an instantaneous rate was sampled
TruncatedSeq _rate_avg;
};
@ -154,6 +191,8 @@ protected:
}
public:
// Sample the allocation rate at GC trigger time if possible. Return the number of allocated bytes that were
// not accounted for in the sample. This must be called before resetting bytes allocated since gc start.
virtual size_t force_alloc_rate_sample(size_t bytes_allocated) override {
size_t unaccounted_bytes;
_allocation_rate.force_sample(bytes_allocated, unaccounted_bytes);

View File

@ -142,6 +142,11 @@ private:
size_t soft_available() const override;
size_t bytes_allocated_since_gc_start() const override;
// Reset the bytes allocated within this generation since the start of GC. The argument initial_bytes_allocated
// is normally zero. In the case that some memory was allocated following the last allocation rate sample that
// precedes the start of GC, the number of bytes allocated is supplied as the initial value of bytes_allocated_since_gc_start.
// We will behave as if these bytes were allocated after the start of GC.
void reset_bytes_allocated_since_gc_start(size_t initial_bytes_allocated);
void increase_allocated(size_t bytes);