Ad removing finalize eventually (Re: JEP 411 Headaches: Instrumenting private methods in the JDK for authorization checkpoints.

Rony G. Flatscher Rony.Flatscher at wu.ac.at
Tue Aug 3 13:08:01 UTC 2021


On 03.08.2021 11:16, Andrew Haley wrote:
> On 8/2/21 7:39 PM, Rony G. Flatscher wrote:
>
>> If the Java ScriptEngine goes out of scope at the Java side its peer
>> ooRexx interpreter instance should be terminated, the same is true
>> for peer objects for either side (Java peer objects for Rexx
>> objects, i.e. Rexx objects being boxed in Java proxy objects, and
>> vice versa, ooRexx peer objects for Java objects such that one can
>> send messages to an ooRexx peer to the Java side where with
>> reflection the appropriate methods get invoked in the corresponding
>> Java object).
> Sure, but Java doesn't know when a Java ScriptEngine goes out of scope.
>
> Here's the scenario: we're running a generational garbage collector.
> Young-generation collections are keeping the heap well within our
> limits, so there's no need to do full collections. The ScriptEngine
> has been running for a while, so is in the old generation. There's no
> reason it will ever be collected. That's why some sort of scoped
> access, such as try with resources, is the right way to go if you
> really need cleanups to be done.

This approach depends on a try-with block, which is easy and straight forward if e.g. reading from a
resource like a file, processing a SLQ statement etc. But "longevity service objects" are hard, if
not impossible, to be put into a (single, central) try-with block. This is especially true for peer
usages (e.g. in ooRexx an object created by one Rexx interpreter instance can be deployed on another
Rexx interpreter instance, and if it is a peer object the peer Java object must stay alive as long
as the ooRexx object is referenced).

>From first, simple tests on Java 8 it seems however, that System.runFinalization() will invoke
finalize() on those Java objects that have no references at the time runFinalization() runs. So it
does not follow the general gc strategy you describe. Running System.gc() does not have that effect,
i.e. running finalize() of the very same Java objects without references at gc() time. So currently
PhantomReferences to these Java objects that have no references would not be put on the queue but at
some undefined later time, possibly never as you describe.

The question then would be whether it was possible to have runFinalization() also look out for
PhantomReference'd Java objects without references and put them on the queue at that point in time.
This of course assumes that runFinalization() not only is able to identify unreferenced Java objects
with a finalize method, but also unreferenced Java objects for which a PhantomReference got created
for. [If so, runFinalization() may remain helpful even after finalize() got eventually removed.]

---rony




More information about the jdk-dev mailing list