Cleaner cleanup
Peter Levart
peter.levart at gmail.com
Thu May 19 16:13:27 UTC 2016
Hi Roger,
Here's the same webrev with an example of use of WeakCleanable that I
have been thinking to propose later (I have done this in 5 minutes):
http://cr.openjdk.java.net/~plevart/jdk9-dev/Cleaner.cleanup/webrev_with_ClassLoader_exmaple/
This example uses WeakCleanable as a lightweight cleanup mechanism that
removes entries from ClassLoader's lock map as soon as they are not
needed any more - usually this is immediately after the class has been
loaded. This keeps the map size from growing and has a nice impact on
final VM footprint.
So the question is whether it is worth keeping those superclass(es) for
such and similar cases. It's not difficult to add them back if/when
needed. The most work is in the test.
Regards, Peter
On 05/19/2016 03:23 PM, Roger Riggs wrote:
>
> Hi,
>
> I haven't had time to look into this thoroughly, but since the
> at-most-once semantics
> have been removed from the Phantom|Weak|SoftCleanable classes and they
> are not
> used anywhere, they should be completely removed also, completing the
> cleanup.
>
> The only function being used (except by the tests) is the primary
> support for Cleaner.register().
>
> Roger
>
> On 5/19/2016 6:35 AM, Christoph Engelbert wrote:
>> Hey Peter,
>>
>> I just realized, there are two mistakes in the Javadoc code example
>> inside the Cleaner Javadoc:
>>
>> private final State; -> private final Statestate;
>> private final Cleaner.Cleanable cleanable -> private final Cleaner.Cleanable cleanable;
>>
>> Chris
>>
>>> On 16 May 2016, at 00:08, Peter Levart <peter.levart at gmail.com> wrote:
>>>
>>> Hi Roger and others,
>>>
>>> When the new Cleaner API was created the implementation of
>>> Cleanable(s) was split into the low-level abstract
>>> [Soft|Weak|Phantom]Cleanable classes to be used internally for
>>> purposes where the footprint matters and their corresponding
>>> CleanerImpl.[Soft|Weak|Phantom]CleanableRef subclasses used as
>>> implementations that take a Runnable cleanup action and are exposed
>>> via the public Cleaner API.
>>>
>>> When thinking of possible JDK internal use cases for the low-level
>>> API, I came to the conclusion that [Soft|Weak|Phantom]Cleanable
>>> classes are not suitable as is, because in cases where footprint
>>> matters, it is usually also the case that the number of
>>> [Soft|Weak|Phantom]Cleanable instances created is larger and that
>>> construction performance also matters. Especially multi-threaded
>>> construction. I'm thinking of the use cases of auto-cleanable
>>> concurrent data structures. In such use cases, the present features
>>> of [Soft|Weak|Phantom]Cleanable classes, namely the guaranteed
>>> just-once cleanup action invocation and keeping the Cleanable
>>> instance reachable until the cleanup action is performed, are
>>> actually not needed and just present footprint and performance
>>> (contention) overhead. They also present an overhead as they don't
>>> allow GC to automatically collect the Cleanable instances if the
>>> data structure containing them becomes unreachable and corresponding
>>> registered cleanup actions obsolete.
>>>
>>> The mentioned features are important for public Cleaner.Cleanable
>>> instances as they are usually used for cleanup of native resources
>>> where the performance of their creation is not so drastically
>>> important and where there is no intrinsic data structure to hold
>>> them reachable.
>>>
>>> I propose to move those features from the
>>> [Soft|Weak|Phantom]Cleanable classes down the hierarchy to the
>>> CleanerImpl.[Soft|Weak|Phantom]CleanableRef subclasses:
>>>
>>> http://cr.openjdk.java.net/~plevart/jdk9-dev/Cleaner.cleanup/webrev.01/
>>> <http://cr.openjdk.java.net/%7Eplevart/jdk9-dev/Cleaner.cleanup/webrev.01/>
>>>
>>>
>>> In this change I also removed the
>>> CleanerImpl.[Soft|Weak]CleanableRef subclasses as they are not
>>> needed and I believe will never be. I also renamed the
>>> CleanerImpl.PhantomCleanableRef subclass to
>>> CleanerImpl.PhantomCleanableImpl.
>>>
>>> Changes to the implementation are straightforward. The most work was
>>> put into the corresponding test. I did some clean-up to it and also
>>> changed it to accommodate for the new behavior of
>>> [Soft|Weak|Phantom]Cleanable classes. The changes speak for itself.
>>> One of the not-so obvious changes was to replace the
>>> CleanableCase.clearRef() action with the
>>> CleanableCase.releaseReferent() action. The old clearRef() action
>>> did not serve any purpose. Whether this method was called or not,
>>> the behavior of the corresponding Cleanable was unchanged as the
>>> Reference instance (referenced from the 'ref' field) was always of
>>> the same strength as the Cleanable itself. So clearing it could not
>>> affect the behavior of the Cleanable.
>>>
>>> I changed 'ref' to hold a direct reference to the referent and
>>> renamed the field to 'referent'. I changed the EV_XXX int constants
>>> to Event enum constants with helper methods used in
>>> CleanableCase.expectedCleanups() method that now returns the number
>>> of expected cleanup invocations - in the PhantomCleanableImpl case
>>> this is the number of expected cleanup action invocations while in
>>> the plain XxxCleanable subclass cases it is the number of
>>> Cleanable.clean() method invocations. I added the no-actions case to
>>> both PhantomCleanableImpl and XxxCleanable cases and extended the
>>> number and combinations of XxxCleanable cases.
>>>
>>> The checkCleaned() method was extended to verify that the number of
>>> cleanup invocations is *no more* and no less then the expected.
>>>
>>> See how WeakKey test is now simplified. This is the typical use-case
>>> for WeakCleanable I was talking about.
>>>
>>>
>>> So, what do you think of this cleanup?
>>>
>>>
>>> Regards, Peter
>>>
>>
>
More information about the core-libs-dev
mailing list