RE: JavaMemoryModel: A problematical case for finalizers

From: Boehm, Hans (hans_boehm@hp.com)
Date: Wed Apr 09 2003 - 15:20:55 EDT


I'm willing to declare the code as written (without synchronization) to be broken. The fully synchronized code must be correct.

The only alternative that we have discussed is to keep "this" live during method execution. That has significant optimization impact, and probably requires essentially all JVMs to be fixed. It also makes an unexpected distinction between a regular method and a static method, with the equivalent of "this" passes as an explicit argument. (I could still live with it, but I would definitely want to hear from most of the implementors first.)

Note that without code to handle the finalizer ordering issues, out.close() may also be called on a previously finalized OutputStream. I could find no statement in the API documentation suggesting that this is safe. Probably it's OK here, since any resulting exception gets dropped, and Foo finalizers do nothing after calling out.close().

Hans

> -----Original Message-----
> From: Bill Pugh [mailto:pugh@cs.umd.edu]
> Sent: Wednesday, April 09, 2003 7:44 AM
> To: javamemorymodel@cs.umd.edu
> 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
-------------------------------
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