[concurrency-interest] Object finalization

Gregg Wonderly gregg at cytetech.com
Mon May 14 17:06:48 EDT 2012

On 5/14/2012 3:49 PM, Boehm, Hans wrote:
> But things are considerably worse than that. References only solve the easy
> problem. The most serious problem in my mind is that finalizers can run, and
> references can be enqueued, while e.g. a method of the object being finalized is
> still running. The fact that the method is still running does not ensure that
> the object itself is still reachable; the method may only need fields that have
> already been cached in registers to complete. This affects finalizers and
> java.lang.ref equally, and explains why probably the large majority of code
> using either one is broken.
> I gave a JavaOne talk about this many years ago (slides at
> http://www.hpl.hp.com/personal/Hans_Boehm/misc_slides/java_finalizers.pdf). It
> is possible, though really ugly and slow to work around the problem. I don’t
> believe anyone does. I was told just after I gave the talk that this explained a
> problem somebody had been trying to track down, so I suspect this actually
> happens occasionally in the wild, though probably not on x86-32.
> Hans
> *From:*concurrency-interest-bounces at cs.oswego.edu
> [mailto:concurrency-interest-bounces at cs.oswego.edu] *On Behalf Of *Bob Lee
> *Sent:* Monday, May 14, 2012 11:01 AM
> *To:* dholmes at ieee.org
> *Cc:* concurrency-interest at cs.oswego.edu
> *Subject:* Re: [concurrency-interest] Object finalization
> On Sun, May 13, 2012 at 11:22 PM, David Holmes <davidcholmes at aapt.net.au
> <mailto:davidcholmes at aapt.net.au>> wrote:
>     I should add the Vitaly's comments prompted me to remember that 'a' and 'b'
>     might refer to objects that themselves have been finalized prior to the
>     current finalizer running. This just reinforces how tricky finalization is.
> Indeed, the finalizers can run in any order, independent of the structure of the
> object graph.
> For those who are interested in learning more, I cover that and half a dozen
> other reasons not to use finalizers in this talk:
> http://www.parleys.com/#id=2657&st=5 <http://www.parleys.com/#id=2657&st=5>

I've tried, over time, and many versions of Java, to use the class that I've 
posted here before, called ReferenceTracker.  It is intended to be similar to a 
WeakRef kind of mechanism, but includes cleanup.  So, you do

public abstract class MyTracker extends ReferenceTracker<SocketHolder,Socket> {}

MyTracker trk = new MyTracker() {
	public void released( Socket s ) {
		try {
		} catch( exception ex ) {


Socket s = ...

SocketHolder sh = new SocketHolder(s);
trk.trackReference( sh, s );

It uses a Phantom reference to 'sh', and a hard reference to 's'
Then, you can have the callback to released() when 'sh' is no longer strongly 

This really should be possible to do.  But, as Hans says, unless you hold a 
strong reference to 'trk', and 'sh', outside of method level binding, this fails 
miserably with the Phantom reference being queued way before the end of the life 
of the object.

Gregg Wonderly

More information about the Concurrency-interest mailing list