Skip to content

8312116: GenShen: make instantaneous allocation rate triggers more timely#29039

Closed
kdnilsen wants to merge 106 commits intoopenjdk:masterfrom
kdnilsen:accelerated-triggers
Closed

8312116: GenShen: make instantaneous allocation rate triggers more timely#29039
kdnilsen wants to merge 106 commits intoopenjdk:masterfrom
kdnilsen:accelerated-triggers

Conversation

@kdnilsen
Copy link
Copy Markdown
Contributor

@kdnilsen kdnilsen commented Jan 5, 2026

After studying large numbers of GC logs with degenerated cycles that have resulted from "late" triggers, we propose the following general improvements:

  1. Track trends in GC times rather than always using the average GC time plus standard deviation. In many situations, GC times trend upward due to, for example, increasing amounts of live data that must be marked as a workload builds up its working set of memory.
  2. Sample allocation rates more frequently than once every 100 ms.
  3. Track trends in allocation rates. In some situations, the allocation rate trends upwards due to, for example, the start of a new phase of execution or a spike in client workload.
  4. When we detect acceleration of allocation rate, predict consumption of memory based on accelerated allocation rates rather than assuming constant allocation rate.

Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8312116: GenShen: make instantaneous allocation rate triggers more timely (Sub-task - P3)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/29039/head:pull/29039
$ git checkout pull/29039

Update a local copy of the PR:
$ git checkout pull/29039
$ git pull https://git.openjdk.org/jdk.git pull/29039/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 29039

View PR using the GUI difftool:
$ git pr show -t 29039

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/29039.diff

Using Webrev

Link to Webrev Comment

kdnilsen and others added 30 commits December 6, 2024 23:35
When allocation rate appears to be accelerating, predict consumption of
memory according to an accelerated rate of consumption.  This expedites
triggers under critical phase changes.
Set both acceleration sample size and momentary spike sample size to 10.
Remove the restriction that momentary spike sample size must be strictly
less than acceleration sample size.  These changes were motivated by
experiments with Extremem workloads.  More experiments are in progress
and further changes may be implemented based on those resuts.
Also refine future predicted gc time to account for possible delay
before we start the GC cycle.
Also tidy up the descriptions of new sample size parameters.
As originally implemented, we apply penalties to the triggering
heuristic every time we experience a degenerated cycle.  This has the
effect of forcing GC triggers to spiral out of control.  This commit
changes the penalty mechanism.  When a degen happens through no fault of
the heuristic triggering mechanism, we do not pile on additional
penalties.  Specifically, we consider that heuristic triggering is not
responsible for a degenerated cycle that is associated with a GC that
began immediately following the end of the previous GC cycle.
… <= _highest_valid_narrow_klass_id) failed: narrowKlass ID out of range (3131947710)

Reviewed-by: shade
(and less expensive monitoring of triggering conditions)
}
// else, leave current_rate = y_max, acceleration = 0
}
// and here also, leave current_rate = y_max, acceleration = 0
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

y_max is no more. fix these two comments.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

range, \
constraint) \
\
product(double, ShenandoahAccelerationSamplePeriod, 0.0145, EXPERIMENTAL, \
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change this option to ms rather than seconds for consistency with existing parameters.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

size_t spike_headroom = capacity / 100 * ShenandoahAllocSpikeFactor;
size_t penalties = capacity / 100 * _gc_time_penalties;
avg_cycle_time = _gc_cycle_time_history->davg() + (_margin_of_error_sd * _gc_cycle_time_history->dsd());
avg_alloc_rate = _allocation_rate.upper_bound(_margin_of_error_sd);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before we test any trigger conditions, we should consider whether a certain minimum amount of memory has been allocated. Move the test from accelerated-triggers below to apply to all triggers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed this code.

}

ShenandoahAdaptiveHeuristics::~ShenandoahAdaptiveHeuristics() {}
void ShenandoahAdaptiveHeuristics::compute_headroom_adjustment(size_t mutator_available) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for mutator_available as an argument and no need to compute byte_allocated_at_start_of_idle.

Comment: if someone changes soft_max_capacity(), this should be called to recompute.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've simplified implementation of compute_headroom_adjustment() and removed unnecessary argument.
I've added a call to compute_headroom_adjustment() when soft_max_capacity is changed.

// before we need to start the next GC.
void start_idle_span() override;

// If old-generation marking finishes during an idle span and immediate old-generation garbage is identified, we will rebuild
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is redundant with start_idle_span or not even necessary (since start_idle_span doesn't need bytes_available.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed resume_idle_span().

// source of feedback to adjust trigger parameters.
TruncatedSeq _available;

ShenandoahFreeSet* _free_set;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use TruncatedSeq::predict_next() for this linear prediction?

Also, can we get rid of _regulator_thread, _control_thread, is_generational?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed _regulator_thread, _control_thread, _is_generational from ShenanoahAdaptiveHeuristics.

TruncatedSeq::predict_next() assumes all data samples are equidistant and does not allow a parameter to predict the value at a specific future time, so it does not provide the same functionality as the abstraction introduced in this PR.

@openjdk openjdk Bot added the merge-conflict Pull request has merge conflict with target branch label Feb 18, 2026
@openjdk openjdk Bot removed the merge-conflict Pull request has merge conflict with target branch label Feb 18, 2026
@kdnilsen
Copy link
Copy Markdown
Contributor Author

kdnilsen commented Mar 3, 2026

/integrate

@openjdk openjdk Bot added the ready Pull request is ready to be integrated label Mar 3, 2026
@openjdk
Copy link
Copy Markdown

openjdk Bot commented Mar 3, 2026

Going to push as commit 0b183bf.
Since your change was applied there have been 192 commits pushed to the master branch:

Your commit was automatically rebased without conflicts.

@openjdk openjdk Bot added the integrated Pull request has been integrated label Mar 3, 2026
@openjdk openjdk Bot closed this Mar 3, 2026
@openjdk openjdk Bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Mar 3, 2026
@openjdk
Copy link
Copy Markdown

openjdk Bot commented Mar 3, 2026

@kdnilsen Pushed as commit 0b183bf.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

_partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector),
_partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector));
old_region_count++;
assert(ac = ShenandoahHeapRegion::region_size_bytes(), "Cannot move to old unless entire region is in alloc capacity");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this assignment expected here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the catch. If the asserted condition is true, this is harmless. But certainly not what was intended.
I will fix in a follow-on patch.

if (i > 0) {
// first sample not included in weighted average because it has no weight.
double sample_weight = x_array[i] - x_array[i-1];
weighted_y_sum = y_array[i] * sample_weight;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be changed to
weighted_y_sum += y_array[i] * sample_weight;
?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will also correct this in a follow-on patch. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hotspot-gc hotspot-gc-dev@openjdk.org integrated Pull request has been integrated shenandoah shenandoah-dev@openjdk.org

Development

Successfully merging this pull request may close these issues.

3 participants