Skip to content

Fix PGC edenSurvivalRate overflow issue#24273

Open
LinHu2016 wants to merge 2 commits into
eclipse-openj9:masterfrom
LinHu2016:fix_edenSurvivalRateCopyForward
Open

Fix PGC edenSurvivalRate overflow issue#24273
LinHu2016 wants to merge 2 commits into
eclipse-openj9:masterfrom
LinHu2016:fix_edenSurvivalRateCopyForward

Conversation

@LinHu2016

Copy link
Copy Markdown
Contributor

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.

@LinHu2016

Copy link
Copy Markdown
Contributor Author

@amicic @dmitripivkine please review the changes, Thanks

* 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.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

let's assert that abort was in progress

/* 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 */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

let's assert it

@amicic amicic added the comp:gc label Jun 30, 2026
@LinHu2016 LinHu2016 force-pushed the fix_edenSurvivalRateCopyForward branch from 0a577cd to 751edd1 Compare June 30, 2026 17:49
@amicic

amicic commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

jenkins test sanity amac jdk21

@LinHu2016 LinHu2016 force-pushed the fix_edenSurvivalRateCopyForward branch 2 times, most recently from d17fdca to ef8aed3 Compare June 30, 2026 22:35
LinHu2016 added 2 commits July 3, 2026 15:00
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>
@LinHu2016 LinHu2016 force-pushed the fix_edenSurvivalRateCopyForward branch from ef8aed3 to 67c8a4d Compare July 3, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants