Fix weak-key hash ephemeron semantics - #1357
Open
Tutez64 wants to merge 1 commit into
Open
Conversation
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.
Problem
hxcpp currently marks every value stored in a weak-key hash during the normal
marking phase, regardless of whether its key is still reachable.
This does not implement ephemeron semantics. In particular, if a value directly
or indirectly references its own key, the following cycle becomes permanently
reachable:
The key is consequently never removed from the map, and the complete object
graph remains alive indefinitely. This can cause substantial heap growth and
increasing GC pause times in long-running applications.
Fix
This change treats weak-key hashes as ephemerons:
hashes are scanned;
another weak hash reachable.
Dead weak keys are then removed by the existing post-GC cleanup.
Tests
The hxcpp native test suite now covers:
Minimal reproduction
HxcppWeakMapEphemeronRepro.zip
It creates 4,000 unreachable keys.
Each mapped value references its key and owns a 64 KiB payload. One additional
key is intentionally retained as a correctness check.
Before this change:
After this change:
Real-world validation
The issue was originally identified in a long-running Haxe/OpenFL application.
In comparable six-minute sessions, this change produced the following results:
Heap censuses also showed that object graphs from completed game levels were
released instead of accumulating.