Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8205887 | 11.0.1 | Stefan Karlsson | P3 | Resolved | Fixed | team |
ZGC has a concept of finalizable marked objects, for objects that are only reachable through the referents of Finalizers.
When objects that have been finalizable marked, are found to also be strongly reachable, the marking strength is updated to strongly marked.
When "processing" SoftReferences, WeakReferences, and Finalizers, the GC checks if the referents are strongly marked, and if not, later pushes the References out to the pending list.
For PhantomReferences, the GC also checks if the referents are finalizable marked, and if not, later pushes the PhantomReferences out to the pending list.
Before the References are processed, the GC "discovers" References that it "encounters" during the marking phase. The GC keeps track of discovered References until the processing phase. If a Reference with a live referent is encountered, it is not discovered, and instead the fields (referent, discovered) are treated as normal fields.
The bug happens when the GC tries to discover a PhantomReference with a finalizable marked referent. Since the referent is already live according to the PhantomReferences's definition of live (finalizable or strongly marked), the PhantomReference is not discovered, and the fields are treated as normal fields. This means that the ordinary strong marking closure is applied to both the referent and the discovered field, causing the marking strength of the referent to be promoted from finalizable marked to strongly marked. This increase in strength isn't problematic for the PhantomReference, since it already considered the referent to be alive. However, any Finalizers that depended on the referent to only be finalizable marked, will now be dropped instead of pushed to the pending list, and therefore the referent will not be finalized.
When objects that have been finalizable marked, are found to also be strongly reachable, the marking strength is updated to strongly marked.
When "processing" SoftReferences, WeakReferences, and Finalizers, the GC checks if the referents are strongly marked, and if not, later pushes the References out to the pending list.
For PhantomReferences, the GC also checks if the referents are finalizable marked, and if not, later pushes the PhantomReferences out to the pending list.
Before the References are processed, the GC "discovers" References that it "encounters" during the marking phase. The GC keeps track of discovered References until the processing phase. If a Reference with a live referent is encountered, it is not discovered, and instead the fields (referent, discovered) are treated as normal fields.
The bug happens when the GC tries to discover a PhantomReference with a finalizable marked referent. Since the referent is already live according to the PhantomReferences's definition of live (finalizable or strongly marked), the PhantomReference is not discovered, and the fields are treated as normal fields. This means that the ordinary strong marking closure is applied to both the referent and the discovered field, causing the marking strength of the referent to be promoted from finalizable marked to strongly marked. This increase in strength isn't problematic for the PhantomReference, since it already considered the referent to be alive. However, any Finalizers that depended on the referent to only be finalizable marked, will now be dropped instead of pushed to the pending list, and therefore the referent will not be finalized.
- backported by
-
JDK-8205887 ZGC: Keeps finalizable marked PhantomReference referents strongly alive
-
- Resolved
-