Re: JavaMemoryModel: Proposal on finalizers

From: Joseph Bowbeer (jozart@blarg.net)
Date: Thu Apr 22 2004 - 02:40:11 EDT


Re-reading some of the finalizer discussion, I'm wondering if detecting the
presence of a subclass with a finalizer and de-optimizing accordingly is too
difficult to rule out. Isn't this the kind of thing that optimizing JVMs do
all the time?

>And this applies whenever x could possibly have a finalizer,
>e.g. as a result of a subclass we haven't seen yet.

It only applies when x has a finalizer, right? (Not when it could possibly
have one?)

----- Original Message -----

From: "Boehm, Hans" <hans.boehm@hp.com>
To: "'Bill Pugh'" <pugh@cs.umd.edu>
Cc: "javamemorymodel-cs.umd.edu" <javamemorymodel@cs.umd.edu>
Sent: Wednesday, April 21, 2004 11:04 AM
Subject: RE: JavaMemoryModel: Proposal on finalizers

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

Hans

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