Re: JavaMemoryModel: Finalization idioms

From: David Detlefs - Sun Microsystems Labs BOS (david.detlefs@sun.com)
Date: Sun May 01 2005 - 21:52:05 EDT


Dan --

> This whole discussion seems to be about getting people to change their
> code to use finalization safely.
>
> But if you're going to advocate that someone change their code, why not
> go all the way and advocate using the {Weak,Phantom}Reference /
> ReferenceQueue mechanism, which was specifically designed (as I
> understand it) as a way to avoid all the problems with the preexisting
> pre-mortem finalization system?
>
> My take is that the pre-mortem finalize() stuff is fine for backwards
> compatibility, and of course every reasonable effort should be made to
> support legacy code, but I don't believe I can think of a case where
> java.lang.ref.* couldn't be used more profitably.

Well, "avoid *all* the problems" seems like a bit of an exageration :-)

You weren't too explicit here, but I'm going to assume that you're
referring to the idea that with Finalizers, everything (detection of
unreachability, placement on a queue, actual execution of finalize
methods) is done by the system, in system threads, and finalizers must
therefore be considered concurrent with mutator code, leading the
problems that Hans is discussion. With weak references, the argument
goes, you can have the weak refs to the unreachable objects placed on
a queue, and then process the queue explicitly (executing the moral
equivalent of finalizers) at well known program points that avoid
these race conditions.

I find this argument a little suspect. Maybe it works for simple
single-threaded programs. In doing weak reference processing
explicitly, you have two dangers:

  1) you won't process the queue often enough, allowing it to grow and
     increase your memory requirements beyond what they ideally ought
     to do.
  2) in avoiding (1), you'll sprinkle your code too liberally with
     calls to a "process_weak_refs_if_necessary", futzing up the code
     and perhaps slowing it down.

And it doesn't really avoid the problem in a multithreaded system, at
least not if any of these objects are reachable from multiple
threads. If Thread A and B create "pseudo-finalizable" objects, and
share a common queue, and each thread executes
"process_weak_refs_if_necessary" calls, then the same problem can
occur: if thread A loses the last ref to an object, then thread B
could execute its pseudo-finalizer code concurrently with subsequent
code executed by A.

So I'm skeptical.

-- 
=============================================================================
Dave Detlefs                           http://www.sunlabs.com/people/detlefs/
Sun Microsystems Laboratories                           david.detlefs@sun.com
1 Network Drive, Burlington, MA 01803-0902                     (781)-442-0841

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



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