RE: JavaMemoryModel: finalization review

From: Sylvia Else (sylviae@optushome.com.au)
Date: Sat Nov 22 2003 - 18:04:23 EST


At 09:39 AM 21/11/2003 -0800, Boehm, Hans wrote:
>The use of finalizers may be motivated by native code, but
>often it won't be.

After some more thought on this, it appears to me that in reality there are
two quite distinct problems that the synchronization approach is trying to
address. In what follows, strictly speaking, I'm using the terms reachable,
etc, to mean finalizer reachable.

1) There is a native process specific resource, such as a file descriptor,
that has to be left in a particular state (eg, closed) for correct future
functioning of the process. A wrapper class is trying to add a finalization
function to a non-Java object.

2) There is a real object in the external world, such as a scratch file,
that the Java program wants to deal with in some way (eg. deleting it),
once the rest of the Java program has finished manipulating it, and a
wrapper class's finalize method is used for this.

In both cases, using a finalize method involves an implied assertion:

If the wrapper instance is unreachable then the wrapped thing is unreachable.

This assertion fails because optimisations can render the wrapper
unreachable sooner than a naive view would suggest.

Repairing the code involves either making the assertion valid, or making it
unnecessary.

In case (2) I would be inclined to argue that this is an abuse of
finalization anyway. The real desire was to attach a finalization action to
the wrapped object, but this is not an option because the objects's class
source is not available for modification. However, the java.lang.ref
classes provide
an alternative approach. Using this approach does create a race between the
operations performed by what ever processes the reference object when its
referent has been cleared, and any finalization actions that do occur on
the wrapped object. This should not be a real problem, because the actions
relate to an external world object, rather than to the wrapped Java Object.

Case (1) cannot be addressed that way, because the handle on the native
resource is not a Java object. That was my motivation for suggesting the
use of the native keyword on the field containing the handle. It is a
request to the compiler to make the assertion valid in the case of this
resource handle.

It is true that the native keyword could then be applied in case (2) as
well, where its use would be counter intuitive given that the link to the
native external world resource is not so direct. If this problem had been
recognised at the language design stage, an appropriate keyword could have
been provided, but adding one now is problematic (though it was done for
assert), hence my suggestion of the use of native.

I still do not see this as a synchronization issue, and remain concerned
about the performance impacts that the synchronization approach will have.

Sylvia.

Postscript

Since case (1) involves a native resource handle, it must also involve a
native method, so the reachability issue can also be solved by passing the
wrapper to the native method, rather than just the handle. The native
method then has to retrieve the handle from the wrapper instance, but at
some cost in making calls back into the JVM.

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



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