finalize() *much* better than PhantomReferences (Re: Ad removing finalize eventually (Re: JEP 411 Headaches: Instrumenting private methods in the JDK for authorization checkpoints.

Kim Barrett kim.barrett at
Thu Aug 5 00:58:51 UTC 2021

> On Aug 4, 2021, at 2:54 PM, Rony G. Flatscher <Rony.Flatscher at> wrote:
> On 04.08.2021 16:35, Rony G. Flatscher wrote:
>> Just for the record: the observed behavior (finalize() of all unreferenced objects runs at
>> runFinalization() time, PhantomReferences are not put on the queue at that time) is the same for
>> Java 6, 8, 11 and 16.
> O.K. now having implemented PhantomReferences to replace the usage of finalize() in the bridge it
> turns out that finalize() gets invoked "magnitudes" of times (100 and more finazable objects in
> different gc runs within a total run of five seconds) more often than their PhantomReferences are
> being put on the reference queue (not a single one!) to allow to carry out the necessary finalizations!
> This is without employing runFinalization(), just the normal garbage collection that takes place in
> a running system. (These tests were run against unit tests of the ooRexx-Java bridge to make sure
> that the tests work the same as before the code changes.)
> ---
> Another test with JavaFX (the quite famous JavaFX address book example implemented in ooRexx) is
> even interactively demonstrative: there were about ten, twelve finalize() runs while operating it
> compared to not a single (!) reference being put on the reference queue in the same time frame!
> Observing this one would wonder whether PhantomReferences would work at all (the implementation
> works, it got tested separately).
> [To be able to compare the behavior I left finalize() in place but only output a debug message with
> a string-id while for the same objects PhantomReferences got created and any such reference removed
> from the reference queue would create a debug message there with the string-id as well and run the
> cleanup method, however this has never happened.]
> ---
> So seriously, please consider to have PhantomReferences being serviced by the gc like finalizable()
> objects, such that gc runs put PhantomReferences on the reference queue as early as possible.

Finalization and PhantomReferences are implemented *identically* as far as
detection and enqueuing, other than the criteria the GC uses for detection.
It's almost all shared code, and that's been true for a long time (possibly
forever, but I don't have easy access to really old versions of the code).
So I think there is a bug in the testing. My guess would be that the
referents of the PhantomReferences aren’t actually phantom reachable. Not
having any knowledge of the code involved, I can’t even speculate on why
that might be. But I have no other explanation to offer.

More information about the jdk-dev mailing list