RFR: 8205163: ZGC: Keeps finalizable marked PhantomReference referents strongly alive
Stefan Karlsson
stefan.karlsson at oracle.com
Mon Jun 18 09:54:14 UTC 2018
Hi all,
Please review this patch to fix a bug where PhantomReferences can cause
otherwise finalizable objects to become considered as strongly reachable.
http://cr.openjdk.java.net/~stefank/8205163/webrev.01/
https://bugs.openjdk.java.net/browse/JDK-8205163
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 later 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.
The proposed patch prevents this problem by always discovering
PhantomReferences with finalizable marked referents. By doing this, the
marking code will not mark the referent as strongly reachable, the
processing code will still drop the PhantomReference. And the
finalizable objects that were incorrectly kept alive, can now be finalized.
This was found in a closed test in higher-tier testing.
Thanks,
StefanK
More information about the hotspot-gc-dev
mailing list