Can an object be finalized while still weakly reachable?

Martin Buchholz martinrb at google.com
Thu May 19 12:54:57 UTC 2016


Martin's law of object pools in the presence of finalizers:

Resurrecting a pooled object with a finalizer can be disastrous as it
can be finalized later while in active use.  Returning an object to
the pool is a common thing to do in close() methods, and close()
methods are reasonable things to call in foreign code finalizers.
So you keep it behind a weak reference at all times, even when in use.
As long as the object remains reachable through the weak reference, it
is safe from finalization.  But the weak reference also permits
finalization for resource reclamation.

On Wed, May 18, 2016 at 7:52 AM, Martin Buchholz <martinrb at google.com> wrote:
> Sherman,
>
> Thank you very much for pointing me at that old thread.  I was indeed
> going down the same path and stumbling over the same obstacles!  I
> still think we can do better, but it's definitely not easy.
>
> On Tue, May 17, 2016 at 8:15 AM, Xueming Shen <xueming.shen at oracle.com> wrote:
>> On 5/17/16 12:55 AM, Martin Buchholz wrote:
>>>
>>> Thanks, Peter.
>>>
>>> My current theory is indeed that I made a mistake, and have
>>> encountered my first real finalization resurrection bug.
>>> ZipFile + Inflater have 4 finalize methods and a WeakHashMap in play!
>>
>> there was a long discussion when we touched that part of the code last time.
>> just
>> for your reference:-)
>>
>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-April/thread.html#6545
>>
>> -sherman
>>
>>> My static reference was finalized because it used to be unreachable,
>>> not because it is now weakly reachable!
>>>
>>> On Mon, May 16, 2016 at 11:49 PM, Peter Levart <peter.levart at gmail.com>
>>> wrote:
>>>>
>>>> Hi Martin,
>>>>
>>>>
>>>>
>>>> On 05/17/2016 05:19 AM, Martin Buchholz wrote:
>>>>>
>>>>> I have some evidence that an object's finalize method can run while a
>>>>> weak reference pointing to it is not yet cleared, which surprised me.
>>>>>
>>>>> E.g.
>>>>> class F { protected void finalize() { assert wref.get() != this; } }
>>>>> static WeakReference wref = new WeakReference(new F());
>>>>>
>>>>> If this is a bug, I can try to give y'all a repro recipe.
>>>>> If not, we should fix the docs
>>>>> """When the weak references to a weakly-reachable object are cleared,
>>>>> the object becomes eligible for finalization."""
>>>>>
>>>>> (It's also quite possible I made a mistake diagnosing this)
>>>>
>>>>
>>>> What can happen with above code is that you get a NPE from dereferencing
>>>> wref in finlailze(). In case NPE is not thrown and the program constructs
>>>> only a single instance of F then assert should succeed.
>>>>
>>>> It is possible that you made a mistake. Can you post the real code?
>>>>
>>>> Regards, Peter
>>>>
>>



More information about the core-libs-dev mailing list