Re: JavaMemoryModel: A problematical case for finalizers

From: Joseph Bowbeer (jozart@csi.com)
Date: Wed Apr 09 2003 - 17:26:14 EDT


Hans Boehm writes:

> What if Foo didn't have a finalizer, so send were fully
> optimized, and then a finalizer were added in a subclass
> of Foo?

If a compiler in a dynamic environment is going to perform optimizations
based on static anaysis, then shouldn't it also be prepared to undo them
when conditions change?

=> But can someone please summarize for the list what we're talking about?
:-) I jumped-in to defend the finalizer guardian idiom, but I've lost track
of what the real issue is.

----- Original Message -----
From: "Boehm, Hans" <hans_boehm@hp.com>
To: "'Joseph Bowbeer'" <jozart@csi.com>; <javamemorymodel@cs.umd.edu>
Sent: Wednesday, April 09, 2003 12:59 PM
Subject: RE: JavaMemoryModel: A problematical case for finalizers

> From: Joseph Bowbeer [mailto:jozart@csi.com]
> Sent: Wednesday, April 09, 2003 10:51 AM
> To: javamemorymodel@cs.umd.edu
> Subject: Re: JavaMemoryModel: A problematical case for finalizers
>
>
> [ After reading Jerry's response, too. ]
>
> Bill Pugh writes:
>
> > Now within the code for send, a VM might try to
> > optimize the call to out.write into a tail call to out.write.
> > The VM could also inline the call to send.
>
> Can we argue that these optimizations should be disallowed in
> the presence
> of a finalizer?
There are certainly other ways to get the same problem. Parameters
to functions aren't automatically kept around, even if the frame
is still on the stack. The fundamental
issue that the Foo objects itself is dead during the out.write() call.
>
> Naively, I ask: Why do we have to assume that the compiler
> will be blind to
> finalizers?
We don't and it doesn't. I suspect most JVMs already generate very
different
code for new X() if X has a finalizer.

But for most of the proposals discussed here, it's hard to limit the
effect on optimization to classes with finalizers. What if Foo didn't have
a finalizer, so send were fully optimized, and then a finalizer were added
in a subclass of Foo?

If there were a clean way to make Bill's code correct while slowing down
only
classes with finalizers, I would certainly want to look at it very
seriously.

Hans

>
>
> ----- Original Message -----
> From: "Bill Pugh" <pugh@cs.umd.edu>
> To: <javamemorymodel@cs.umd.edu>
> Sent: Wednesday, April 09, 2003 7:43 AM
> Subject: JavaMemoryModel: A problematical case for finalizers
>
>
>
> In talking about finalizers with Doug Lea, I mentioned a scenario
> which I thought everyone knew about but Doug hadn't considered. He
> suggested I share it
> with everyone.
>
> Consider
>
> public class Foo {
> OutputStream out;
>
> public Foo(...) {
> out = ...;
> }
>
> public void send(...) {
> byte [] buf = ...;
> out.write(buf);
> }
> protected void finalize() {
> out.close();
> }
> }
>
> Now consider the code:
>
> { Foo f = new Foo(...);
> f.send(...);
> }
>
> Now within the code for send, a VM might try to optimize the call to
> out.write into a tail call to out.write.
>
> The VM could also inline the call to send.
>
> In this situation, there wouldn't be any live reference to the Foo
> object from the stack during the call to write. However, the write
> method could take a very long time to execute if it is pushing a
> large amount of data down a narrow pipe. So the Foo object could be
> finalized, and the output stream be closed, while the output stream
> is still being written to.
>
> Are we happy to declare such code broken?
>
> Note that declaring the send and finalize methods as synchronized
> with fix the problem. So would a call to System.keepAlive(this) at
> the end of the send method, if people are interested in that.
>
> Bill
>

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



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