Re: JavaMemoryModel: Implementing KeepAlive

From: Jerry Schwarz (
Date: Wed Apr 21 2004 - 20:30:58 EDT

At 12:02 PM 4/21/2004, Bill Pugh wrote:

OK, here is a class that implements keepAlive:

public class FinalizerHelp {
  static volatile Object v;
  public static void keepAlive(Object o) {
    v = o;
    v = null;
  public static void getReadyToFinalize() {
    Object o = v;

Take Hans'es example and add a call to keepAlive.
for (i = 0; i < 10; ++i) {
  sum += x.a[i];

I don't think this has the desired effect. The compiler first moves the reference to x outside the loop and inlines keepAlive to

    v = o;
    v = null;

Then it eliminates v=o. It doesn't actually have to do the store because it's allowed to pretend that no other thread will be scheduled between the two assignments. At this point it has reason (other than it's effect on when finalizers might be called) to hold onto a. 
GC comes along and calls the finalizer while the loop is still in progress.

I suppose you can argue that since you've created a happens-before relationship between the uses of x in the loop and its uses in the finalizer that the compiler isn't allowed to do this.  But that argument only applies if we know the use in the finalizer comes after the assignment in keepAlive and we don't know that because the JLS explicitly says that the finalizer can be called earlier than a "naive" reader would expect.

The semantics we provided to ensure that finalizer guardians would work
will also ensure that an object is still reachable if we are going to
write a reference to that object into a global variable.

Because the write is a volatile write, preceding memory accesses can't
be reordered with the call to keepAlive.

The one point of ugliness here is that each finalizer should call


JavaMemoryModel mailing list -
------------------------------- JavaMemoryModel mailing list -

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