RFR 9: 8138696 : java.lang.ref.Cleaner - an easy to use alternative to finalization

Mandy Chung mandy.chung at oracle.com
Tue Oct 13 20:59:12 UTC 2015

> On Oct 13, 2015, at 6:56 AM, Roger Riggs <roger.riggs at oracle.com> wrote:
> When considering how to update the existing classes with finalize methods, it became clear that
> refactoring would be needed to separate out the state needed for the cleanup from public object
> that was being finalized into a separate object it would provide the cleanup behavior as well.
> In simple cases, it is just a copy of the native address or file descriptor.  In other cases, like
> FileIn/OutputStream it is references to other objects.  In cases like FileDescriptor and Zip streams
> the cleanup state is not just a native resource.
> The abstract XXXCleanup types make it easy to encapsulate the needed behavior and state.
>> Second, the original sun.misc.Cleaner only handles phantom references.
>> What are the use cases for weak and soft cleaners?
> WeakReferences are sometimes used but since it is extra coding to clean them it tends
> not to be implemented.
> For example, sun.beans.WeakCache; it was just not worth the code to handle the weak refs completely.
> In another case, the ldap connection pool only cleans up connections when opening
> a new pooled connection.
> Having easy to use and more active cleanup would release resources sooner and
> reduce overall resource requirements.

There are existing use of SoftReference and WeakReference in the JDK that has very simple dispose / clean method.  This Cleaner API can benefit those cases if they are replaced to use the Cleaner API.  

It’d be useful to replace a couple of uses in the JDK with the new Cleaner API and include in the webrev.   It could be different changesets that you can decide when it’s ready to be integrated.   Same to include a few finalizers replaced would be good.

>> Finally, how important is it to be able to unregister a cleaner?  In
>> all the years we've had sun.misc.Cleaner that capability has never
>> been needed, and leaving it out would simplify the API.
> Recently there was a long discussion on core-libs [1] about making the cleanup of MappedByteBuffers
> more timely to free up the memory sooner.  If there was an explicit release operation on
> either of those, then the cleaner would want to be unregistered or it would need to be at-most-once.

But this Cleaner API is not intended for MappedByteBuffer to replace its current use of sun.misc.Cleaner, right?  I think it’s fine to keep this API for the common cases but not the cases that require on-demand clean up.

> Encapsulating the cleanup state and behavior allows it to be invoked consistently both when the
> object is closed or is found to be unreachable.  The cleanup code is not repeated, and it is
> easy to ensure that is invoked at most once.

> The other important aspect is that when the cleanup is performed explicitly (on close)
> the ref is cleared and the overhead associated with reference processing is eliminated.
> Currently, with finalizers, the finalizable refs still have to be processed, even if object has been closed.

This Cleaner API is intended to provide an easy to use alternative to finalization. I have been considering performance and promptness of reference processing separated from this proposed API (GC might be the appropriate place to speed up reference processing performance - what I refer to is common use of finalizers but not the resources that require promptness such as mapped byte buffer).

It’s still unclear if it should allow a cleaner to be cleaned explicitly and unregistered.  


More information about the core-libs-dev mailing list