RFR 9: 8138696 : java.lang.ref.Cleaner - an easy to use alternative to finalization
Roger Riggs
Roger.Riggs at Oracle.com
Wed Dec 16 19:47:05 UTC 2015
Hi Peter,
It was a bit more involved than I expected, mostly in the tests to make
this change.
Is this what you expected? (just the deltas, I'll merge the patches
before pushing).
http://cr.openjdk.java.net/~rriggs/webrev-cleaner-8138696-no-clear/
Thanks, Roger
On 12/15/2015 6:01 PM, Peter Levart wrote:
>
>
> On 12/15/2015 11:48 PM, Roger Riggs wrote:
>> Hi Peter,
>>
>> That will break up clearing the ref when the Cleanable is explicitly
>> cleaned.
>> Reference.clear() needs to be called from Cleanable.clean().
>
> From PhantomCleanable (the superclass of PhantomCleanableRef):
>
> 253 @Override
> 254 public final void clean() {
> 255 if (remove()) {
> 256 super.clear();
> 257 performCleanup();
> 258 }
> 259 }
> 260
> 261 /**
> 262 * Unregister this PhantomCleanable and clear the reference.
> 263 * Due to inherent concurrency, {@link #performCleanup()}
> may still be invoked.
> 264 */
> 265 @Override
> 266 public final void clear() {
> 267 if (remove()) {
> 268 super.clear();
> 269 }
> 270 }
>
>
> ... clean() calls super.clear(), which is "invokespecial" (not a
> virtual dispatch).
>
>
> Regards, Peter
>
>>
>> it might be nice to block that but to do so we'd need to go back to
>> separate objects
>> for the Reference and the Cleanable and we worked hard to get to a
>> single object.
>>
>> Roger
>>
>>
>> On 12/15/2015 5:38 PM, Peter Levart wrote:
>>> Hi Roger,
>>>
>>> Just one thing about implementation:
>>>
>>> Since the type exposed to user is Cleaner.Cleanable that has only a
>>> single method clean(), it would be good if the implementation class
>>> (CleanerImpl.PhantomCleanableRef) overrode
>>> CleanerImpl.PhantomCleanable.clear() method and threw
>>> UnsupportedOperationException, otherwise users will be tempted to
>>> cast the returned Cleaner.Cleanable to Reference and invoke clear()
>>> method to de-register cleanup action without invoking it. This is
>>> the only remaining public Reference method that is not disabled this
>>> way.
>>>
>>> Regards, Peter
>>>
>>> On 12/09/2015 07:40 PM, Roger Riggs wrote:
>>>> Hi,
>>>>
>>>> The example is revised to caution about inner classes and lambdas.
>>>>
>>>> [1]http://cr.openjdk.java.net/~rriggs/webrev-cleaner-8138696/
>>>> [2]http://cr.openjdk.java.net/~rriggs/cleaner-doc/index.html
>>>>
>>>> Thanks, Roger
>>>>
>>>> On 12/9/2015 11:04 AM, Peter Levart wrote:
>>>>> Hi Chris,
>>>>>
>>>>> On 12/09/2015 04:03 PM, Chris Hegarty wrote:
>>>>>> Peter,
>>>>>>
>>>>>> On 09/12/15 07:05, Peter Levart wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> I think the only way to try to prevent such things is with a good
>>>>>>> example in javadoc that "screams" of possible miss-usages.
>>>>>>>
>>>>>>>
>>>>>>> public static class CleanerExample implements AutoCloseable {
>>>>>>>
>>>>>>> private static final Cleaner cleaner = ...; //
>>>>>>> preferably a
>>>>>>> shared cleaner
>>>>>>>
>>>>>>> private final PrivateNativeResource pnr;
>>>>>>>
>>>>>>> private final Cleaner.Cleanable cleanable;
>>>>>>>
>>>>>>> public CleanerExample(args, ...) {
>>>>>>>
>>>>>>> // prepare captured state as local vars...
>>>>>>> PrivateNativeResource _pnr = ...;
>>>>>>>
>>>>>>> this.cleanable = cleaner.register(this, () -> {
>>>>>>> // DON'T capture any instance fields with
>>>>>>> lambda since
>>>>>>> that would
>>>>>>> // capture 'this' and prevent it from becoming
>>>>>>
>>>>>> I assume that the WARNING should include anonymous inner classes too
>>>>>> ( which I expect are quite common, though less now with lambda ) ?
>>>>>>
>>>>>> Is "leaking" 'this' in a constructor a potential issue with respect
>>>>>> to the visibility of pnr? As well as causing red-squiggly lines in
>>>>>> the IDE ;-)
>>>>>
>>>>> 'this' only leaks to the 'referent' field of PhantomReference
>>>>> where by definition is not accessible.
>>>>>
>>>>> 'this' can become phantom-reachable before CleanerExample
>>>>> constructor ends. But this is harmless, because the code that may
>>>>> execute at that time does not access the object any more, so the
>>>>> object may be safely collected.
>>>>>
>>>>> Cleanup action can run at any time after registration even before
>>>>> CleanerExample constructor ends. But this is harmless too, because
>>>>> it only accesses PrivateNativeResource which is fully constructed
>>>>> before registration of cleanup action.
>>>>>
>>>>> I see no issues apart from IDE(s) not seeing no issues.
>>>>>
>>>>> Regards, Peter
>>>>>
>>>>>>
>>>>>> -Chris.
>>>>>>
>>>>>>
>>>>>>> phantom-reachable!!!
>>>>>>> _pnr.close();
>>>>>>> });
>>>>>>>
>>>>>>> this.pnr = _pnr;
>>>>>>> }
>>>>>>>
>>>>>>> public void close() {
>>>>>>> cleanable.clean();
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> Regards, Peter
>>>>>>>
>>>>>
>>>>
>>>
>>
>
More information about the core-libs-dev
mailing list