-
Notifications
You must be signed in to change notification settings - Fork 5.8k
8260044: Parallel GC: Concurrent allocation after heap expansion may cause unnecessary full gc #2309
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back kbarrett! A progress list of the required criteria for merging this PR into |
@kimbarrett Setting summary to |
@kimbarrett The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
HeapWord* res; | ||
do { | ||
res = cas_allocate_noexpand(word_size); | ||
// Retry failed allocation if expand succeeds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"... but allocation did not." would be nice to be added to this comment to be complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a "failed allocation".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed :)
if (bytes == 0) { | ||
return; | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer if the code would guarantee
or at least assert
that bytes > 0
because returning true
here seems scary wrt to the loop.
All code paths seem to cover this situation already, i.e. with word_size == 0
this should not be called.
But if you think it's not a big issue, we can keep it. This is pre-existing of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I will make sure a 0 size never gets here and assert/guarantee, or otherwise figure out what to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed various quick returns on zero size to instead be asserts, since none of them should ever be called with a zero size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm. Thanks.
HeapWord* res; | ||
do { | ||
res = cas_allocate_noexpand(word_size); | ||
// Retry failed allocation if expand succeeds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed :)
@kimbarrett This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 1 new commit pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
The problem being addressed here is closely related to the "expand storm" Reversing the order of fixes doesn't work very well either, as avoiding the New commit "avoid expand storms" adds that fix. It's a little bit kludgy Testing: /issue JDK-8260045 |
@kimbarrett |
/summary Loop to retry allocation if expand succeeds. Treat space available after obtaining expand lock as expand success. |
@kimbarrett Updating existing summary to |
/integrate |
@kimbarrett Since your change was applied there has been 1 commit pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit 6a84ec6. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Still looks good. Thanks. (I am aware this change has already been integrated). |
Please review this change to ParallelGC to avoid unnecessary full GCs when
concurrent threads attempt oldgen allocations during evacuation.
When a GC thread fails an oldgen allocation it expands the heap and retries
the allocation. If the second allocation attempt fails then allocation
failure is reported to the caller, which can lead to a full GC. But the
retried allocation could fail because, after expansion, some other thread
allocated enough of the available space that the retry fails. This can
happen even though there is plenty of space available, if only that retry
were to perform another expansion.
Rather than trying to combine the allocation retry with the expansion (it's
not clear there's a way to do so without breaking invariants), we instead
simply loop on the allocation attempt + expand, until either the allocation
succeeds or the expand fails. If some other thread "steals" space from the
expanding thread and causes its next allocation attempt to fail and do
another expansion, that's functionally no different from the expanding
thread succeeding and causing the other thread to fail allocation and do the
expand instead.
This change includes modifying PSOldGen::expand_to_reserved to return false
when there is no space available, where it previously returned true. It's
not clear why it returned true; that seems wrong, but was harmless. But it
must not do so with the new looping behavior for allocation, else it would
never terminate.
Testing:
mach5 tier1-3, tier5 (tier2-3, 5 do a lot of ParallelGC testing)
/summary Loop to retry allocation if expand succeeds.
Progress
Issues
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/2309/head:pull/2309
$ git checkout pull/2309