Fix PGC edenSurvivalRate overflow issue#24273
Open
LinHu2016 wants to merge 2 commits into
Open
Conversation
Contributor
Author
|
@amicic @dmitripivkine please review the changes, Thanks |
amicic
reviewed
Jun 30, 2026
| * the forwarding pointer was installed) is also counted again during the abort scan of the source region. | ||
| * So _scanBytesEden might be double-counted, then cause edenSurvivorCount is bigger than edenCountBeforeCollect. | ||
| * for this case, set edenSurvivorCount = edenCountBeforeCollect. | ||
| */ |
Contributor
There was a problem hiding this comment.
let's assert that abort was in progress
amicic
reviewed
Jun 30, 2026
| /* Eden count could be 0 in special case, after compaction if there is still no free region for scheduling eden(eden count = 0), | ||
| will skip update Survival Rate */ | ||
| if (0 != edenCountBeforeCollect) { | ||
| /* SurvivalRate should never be over 1.0 */ |
0a577cd to
751edd1
Compare
Contributor
|
jenkins test sanity amac jdk21 |
d17fdca to
ef8aed3
Compare
The edenSurvivalRate is representing the number of regions out of those allocated for this Eden which survived(typically 0.0 <= the Rate <= 1.0). The edenSurvivalRate overflow (> 1.0) might cause incorrect Heap and Eden size change(unexpected spike/noise) and for some cases might cause zero free memory and trigger out of memory exception. the issue is not regression, but just exposed by recent edenResize change(it might cause indirect serious GC performance issues, but did not trigger any crashes/exceptions/assertions). There are two different overflow cases, one is major, another is minor. Major issue is incorrect edenCountBeforeCollect. During GC, the heap may expand to allow the current collection to continue. A heap resize triggers an eden size recalculation without allowing further heap expansion (heap reconfiguration). As a result, the newly calculatedneden size can differ significantly from the eden size at the start of the collection, causing the SurvivalRate calculation to become inaccurate. Therefore, set copyForwardStats->_edenEvacuateRegionCount (instead of getCurrentEdenSizeInRegions(env)) to edenCountBeforeCollect. Minor issue is _scanBytesEden double-counts. When abort is in progress, every Eden object scanned in abort-recovery contributes to _scannedBytes. But an object that was partially copied before abort (the copy succeeded, the forwarding pointer was installed) is also counted again during the abort scan of the source region. So _scanBytesEden might be double-counted, then cause edenSurvivorCount is bigger than edenCountBeforeCollect. For this case, set edenSurvivorCount = edenCountBeforeCollect. Signed-off-by: lhu <linhu@ca.ibm.com>
This happens at the first PGC after a GMP: the previous Eden survivors are now ADDRESS_ORDERED_MARKED with logicalAge == 0. They enter the evacuate set as non-Eden regions, but their surviving objects spill into age-0 survivor regions counted as Eden survivors. It could cause _edenSurvivorRegionCount exceeds _edenEvacuateRegionCount and _edenSurvivalRateCopyForward is over 1.0. count "logicalAge == 0 non-Eden regions"(previous marked, but haven't go through PGC) as Eden regions, produces a self-consistent _edenSurvivalRateCopyForward with no additional machinery. Signed-off-by: lhu <linhu@ca.ibm.com>
ef8aed3 to
67c8a4d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The edenSurvivalRate is representing the number of regions out of those allocated for this Eden which survived(typically 0.0 <= the Rate <= 1.0).
The edenSurvivalRate overflow (> 1.0) might cause incorrect Heap and Eden size change(unexpected spike/noise) and for some cases might cause zero free memory and trigger out of memory exception. the issue is not regression, but just exposed by recent edenResize change(it might cause indirect serious GC performance issues, but did not trigger any crashes/exceptions/assertions).
There are two different overflow cases, one is major, another is minor. Major issue is incorrect edenCountBeforeCollect.
During GC, the heap may expand to allow the current collection to
continue. A heap resize triggers an eden size recalculation without
allowing further heap expansion (heap reconfiguration). As a result,
the newly calculatedneden size can differ significantly from the eden
size at the start of the collection, causing the SurvivalRate
calculation to become inaccurate. Therefore, set
copyForwardStats->_edenEvacuateRegionCount (instead of
getCurrentEdenSizeInRegions(env)) to edenCountBeforeCollect.
Minor issue is _scanBytesEden double-counts.
When abort is in progress, every Eden object scanned in abort-recovery
contributes to _scannedBytes. But an object that was partially copied
before abort (the copy succeeded, the forwarding pointer was installed)
is also counted again during the abort scan of the source region.
So _scanBytesEden might be double-counted, then cause edenSurvivorCount
is bigger than edenCountBeforeCollect.
For this case, set edenSurvivorCount = edenCountBeforeCollect.