Fate of {System|Runtime}.runFinalization (Re: Ad removing finalize eventually

Hans Boehm hboehm at google.com
Mon Aug 2 23:27:07 UTC 2021

Thanks for all your helpful responses!

I was talking about a somewhat different problem. Let's assume you're using
References to manage some type of limited resource S, e.g. a certain type
of graphics memory, or file descriptors, or whatever. Each S has a
PhantomReference that is enqueued when S is dropped, and the code
processing the queue will deallocate the corresponding hardware or native
resource. (This of course should be avoided when possible, but it isn't
always possible.)

When I try to allocate an S, and there aren't any more, I really want to
wait until the following have happened to either free one up or convince
myself I'm really out of resources:

1) The garbage collector has run at least once. I can do (a sufficient
approximation of) that with System.gc() or the like.
2) PhantomReferences with a dead Referent have been enqueued. It's not
clear to me that there is a portable way to do this. (System.gc() might
sometimes do that. If not, System.gc(); System.runFinalization() probably
does. But it's not 100% clear to me what the intent was.)
3) The entire associated ReferenceQueue has been processed once. If my
cleanup code is built directly on PhantomReferences, I can implement that.
If I use Cleaners, this at least seems to get inelegant.

I can't explicitly enqueue anything, since I still don't know what has been
dropped. I just know that I appear to be out of S's, possibly because my
machine has a zillion bytes of memory, and there's no real reason to
actually run the garbage collector to reclaim memory.

So my concern is really how to do (2) and (3) in the new world, i.e. wait
until unreachable objects found by the last GC have been cleaned. With
finalizers, System.runFinalization() effectively did the equivalent of that
(potentially modulo the deadlock questions).


On Mon, Aug 2, 2021 at 2:34 PM Erik Osterlund <erik.osterlund at oracle.com>

> Hi Hans,
> > On 2 Aug 2021, at 22:53, Hans Boehm <hboehm at google.com> wrote:
> >
> > I think we will eventually need something analogous to runFinalization()
> > for Cleaners and/or References. If you are out of some resource managed
> by
> > Cleaners and want to allocate another one, how do you wait for resources
> of
> > that kind to be reclaimed? What do you do if you're testing code using
> > Cleaners or References to reclaim resources?
> I thought that’s the purpose ish for java.lang.ref.Reference.enqueue(). It
> lets the cleanup run before the GC gets around to it. If you need more
> precise synchronization, that can seemingly be managed by the queue owner.
> /Erik
> > This may also be a great opportunity to resolve the long-standing issue
> of
> > whether it's safe to call runFinalization() with user-visible locks held.
> > What happens when runFinalization's caller holds a lock needed by a
> > finalizer? This should be more tractable for Cleaners and References,
> since
> > it's easier to maintain separate queues for different classes.
> >
> >
> >> On Mon, Aug 2, 2021 at 6:12 AM Rony G. Flatscher <
> Rony.Flatscher at wu.ac.at>
> >> wrote:
> >>> On 01.08.2021 21:02, Alan Bateman wrote:
> >>> On 01/08/2021 14:01, Rony G. Flatscher wrote:
> >>>> Maybe a last question in this context: is it planned that
> >>>> {System|Runtime.getRuntime()}.runFinalization() gets removed when
> >> finalize() gets removed? If so,
> >>>> would there be an equivalent?
> >>> There isn't a proposal or JEP yet for the next steps for finalization.
> >> The runFinalization method
> >>> should probably be deprecated. It might be that the method is
> eventually
> >> "degraded" to do nothing
> >>> or throw an exception, too early to say. Aside from System.gc, there
> >> isn't an API exposed to
> >>> "help" reference processing.
> >> Thank you very much for clarifying, so it is safest to remove its usage!
> >> ---rony

More information about the jdk-dev mailing list