Re: JavaMemoryModel: Proposal on finalizers

From: Bill Pugh (pugh@cs.umd.edu)
Date: Wed Apr 21 2004 - 14:43:08 EDT


On Apr 21, 2004, at 2:04 PM, Boehm, Hans wrote:

>
> [Bill writes, omitting the 5/6 I agree with:]
>> * all active uses of an object (accessing a field of the
>> object, synchronizing on the object, or writing a reference
>> to an object) count as "reaching" the object from the
>> thread performing the action.
>
> Counting an ordinary read as "reaching" the object seems nearly vacuous
> if you allow the normal reordering of the read. And I think it's a
> significant optimization change if you don't.

Correct. Because the compiler is allowed to reorder uses, this has
pretty minimal impact. The only real way to ensure something is kept
alive while you are updating things referenced from the object
is by using synchronization or a volatile write.

> Consider
>
> for (i = 0; i < 10; ++i) {
> sum += x.a[i];
> }
>
> If the access in the loop has to keep x live (e.g. because x's
> finalizer
> clobbers x.a), I can't move the pointer read of x.a out of the loop,
> without
> adding code to explicitly keep x around. And this applies whenever x
> could
> possibly have a finalizer, e.g. as a result of a subclass we haven't
> seen yet.
>
> And this guarantee still isn't very useful, since the "reaching" read
> typically precedes the global data structure access which really needs
> to
> be protected from the finalizer.
>
> If this was meant to have any content, I think there is no way we can
> make such
> a drastic change at this stage. This will have orders of magnitude
> more
> implementation impact than keepLive().

No impact.

>
>> So there are two recommended ways of writing finalizers:
>>
>> * The finalizer only depends on seeing writes performed
>> in the constructor of that object
>>
>> * The finalizer using synchronization to ensure that
>> it is correctly synchronized with all the writes it
>> needs to see
>>
> You need to consider the underlying global data structure which
> is cleaned up by the finalizer. Even if the object contains only
> final fields, you may need synchronization (or keepLive()) on the
> object to ensure that the cleanup does not happen early.
>
> The first option basically doesn't exist.

I'm not sure I follow.

Any writes performed during construction, even if they are to objects
other than
the object being finalized, will be visible to the finalizer.

And if you are accessing a global, shared structure, you better be
using synchronization.

Bill

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:05 EDT