RE: JavaMemoryModel: Proposal on finalizers

From: Boehm, Hans (
Date: Wed Apr 21 2004 - 14:04:43 EDT

[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. 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().

> 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.

JavaMemoryModel mailing list -

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