![]() |
finalize called on an object that's still in scope?
I've got some code that looks sort of like
LineupProxy lineup = new LineupProxySubClass(); lineup.connect(); while(true) { try { Thread.sleep(5000); } catch (InterruptedException ie) {}} } It's supposed to run forever. Methods within the LineupProxy get called through RMI and it just sits there handling events. But last night, for no reason that I can fathom, the LineupProxySubClass.finalize() method got called, which did bad things. We've just started using 1.5_011, up from 1.4, and I don't think it ever happened in 1.4 although we have our suspicious about some other odd happenings. Is this a known bug in 1.5? -- Paul Tomblin <ptomblin@xcski.com> http://blog.xcski.com/ I don't see what C++ has to do with keeping people from shooting themselves in the foot. C++ will happily load the gun, offer you a drink to steady your nerves, and help you aim. -- Peter da Silva |
Re: finalize called on an object that's still in scope?
Paul Tomblin wrote:
... >...Is this a known bug in 1.5? Best way to find out, is to search the bug database. <http://bugs.sun.com/bugdatabase/index.jsp> -- Andrew Thompson http://www.athompson.info/andrew/ Message posted via http://www.javakb.com |
Re: finalize called on an object that's still in scope?
Paul Tomblin wrote:
> I've got some code that looks sort of like > > LineupProxy lineup = new LineupProxySubClass(); > lineup.connect(); > while(true) > { > try { Thread.sleep(5000); } catch (InterruptedException ie) {}} > } > > It's supposed to run forever. Methods within the LineupProxy get called > through RMI and it just sits there handling events. But last night, for > no reason that I can fathom, the LineupProxySubClass.finalize() method got > called, which did bad things. We've just started using 1.5_011, up from > 1.4, and I don't think it ever happened in 1.4 although we have our > suspicious about some other odd happenings. Is this a known bug in 1.5? From a language and VM spec point of view, that looks entirely legal. The object is not reachable, therefore it can be finalised. From a practical point of view, I'm not entirely sure what is happening here. Perhaps lineup and ie share the same local variable slot. You are sleeping for 5 seconds at a time. So possibly the method may get compiled after a few hours. The obvious fix is to assign lineup to a volatile variable every time around the loop, but that's just an evil hack for deeper design issues. But it's technically worse than that. You need a happens-before edge to make sure your last use happens-before the finaliser is called, which is not automatic. Construction is finished before finalisation, but not random methods. The bottom line is that finalisers are difficult, therefore avoid them. Tom Hawtin |
Re: finalize called on an object that's still in scope?
In a previous article, ptomblin+netnews@xcski.com (Paul Tomblin) said:
>I've got some code that looks sort of like > > LineupProxy lineup = new LineupProxySubClass(); > lineup.connect(); > while(true) > { > try { Thread.sleep(5000); } catch (InterruptedException ie) {}} > } > >It's supposed to run forever. Methods within the LineupProxy get called >through RMI and it just sits there handling events. But last night, for >no reason that I can fathom, the LineupProxySubClass.finalize() method got >called, which did bad things. We've just started using 1.5_011, up from Oh, I should mention that I "kill -3"'ed the java process, and the thread dump showed that it's still in the while(true) loop, so it didn't exit by accident. -- Paul Tomblin <ptomblin@xcski.com> http://blog.xcski.com/ I'm pro-lifevest and I boat. |
Re: finalize called on an object that's still in scope?
Paul Tomblin wrote:
> I've got some code that looks sort of like > > LineupProxy lineup = new LineupProxySubClass(); > lineup.connect(); > while(true) > { > try { Thread.sleep(5000); } catch (InterruptedException ie) {}} > } To prevent your local variable from dereferencing, cause referencing it in a loop, e.g. that way: while(true) { try { Thread.sleep(5000); } catch (InterruptedException ie) {}} lineup.hashCode(); // or System.identityHashCode(), or ... } piotr |
Re: finalize called on an object that's still in scope?
In a previous article, Piotr Kobzda <pikob@gazeta.pl> said:
>Paul Tomblin wrote: >> I've got some code that looks sort of like >> >> LineupProxy lineup = new LineupProxySubClass(); >> lineup.connect(); >> while(true) >> { >> try { Thread.sleep(5000); } catch (InterruptedException ie) {}} >> } > >To prevent your local variable from dereferencing, cause referencing it >in a loop, e.g. that way: > > while(true) > { > try { Thread.sleep(5000); } catch (InterruptedException ie) {}} > lineup.hashCode(); // or System.identityHashCode(), or ... > } Is this a hack, or is it normal that a local variable would be destructed before it goes out of scope? -- Paul Tomblin <ptomblin@xcski.com> http://blog.xcski.com/ The Borg assimilated my race & all I got was this T-shirt. |
Re: finalize called on an object that's still in scope?
Paul Tomblin wrote:
> In a previous article, Piotr Kobzda <pikob@gazeta.pl> said: >> Paul Tomblin wrote: >>> I've got some code that looks sort of like >>> >>> LineupProxy lineup = new LineupProxySubClass(); >>> lineup.connect(); >>> while(true) >>> { >>> try { Thread.sleep(5000); } catch (InterruptedException ie) {}} >>> } >> To prevent your local variable from dereferencing, cause referencing it >> in a loop, e.g. that way: You mean from becoming unreachable. Dereferencing is what you are proposing to do to it. http://www.google.co.uk/search?q=define%3Adereference That doesn't work, technically. >> while(true) >> { >> try { Thread.sleep(5000); } catch (InterruptedException ie) {}} >> lineup.hashCode(); // or System.identityHashCode(), or ... >> } > > Is this a hack, or is it normal that a local variable would be destructed > before it goes out of scope? Destructed is a C++ term. It's probably a bad idea not to think of Java finalising and destructing, because they are very different concepts. A finaliser is not the opposite of a constructor. The local variable is not finalised. The object that was once referred to by the local variable is (or may be) finalised. Scope doesn't actually have anything to do with it at all. Tom Hawtin |
Re: finalize called on an object that's still in scope?
In a previous article, Tom Hawtin <usenet@tackline.plus.com> said:
>>> while(true) >>> { >>> try { Thread.sleep(5000); } catch (InterruptedException ie) {}} >>> lineup.hashCode(); // or System.identityHashCode(), or ... >>> } >> >> Is this a hack, or is it normal that a local variable would be destructed >> before it goes out of scope? > >Destructed is a C++ term. It's probably a bad idea not to think of Java >finalising and destructing, because they are very different concepts. A >finaliser is not the opposite of a constructor. > >The local variable is not finalised. The object that was once referred >to by the local variable is (or may be) finalised. Scope doesn't >actually have anything to do with it at all. But the local variable is still in scope, so therefore is still referring to it. I would not expect the object to be garbage collected/finalized/destructed and if it is, then there is something seriously wrong happening here. -- Paul Tomblin <ptomblin@xcski.com> http://blog.xcski.com/ Usenet is a co-operative venture, backed by nasty people - follow the standards. -- Chris Rovers |
Re: finalize called on an object that's still in scope?
Tom Hawtin wrote:
> You mean from becoming unreachable. You right! :) > Dereferencing is what you are > proposing to do to it. > > http://www.google.co.uk/search?q=define%3Adereference > > That doesn't work, technically. Ah, I always thought dereferencing is the apposite of referencing. As decompilation is the opposite of compilation, etc. Thanks Tom for correcting my (wrong) definition. piotr |
Re: finalize called on an object that's still in scope?
Paul Tomblin wrote:
>> The local variable is not finalised. The object that was once referred >> to by the local variable is (or may be) finalised. Scope doesn't >> actually have anything to do with it at all. > > But the local variable is still in scope, so therefore is still referring > to it. I would not expect the object to be garbage > collected/finalized/destructed and if it is, then there is something > seriously wrong happening here. Nothing is wrong here. Each local lives (as a reference) in a local stack frame space, which (space) is a subject to reuse whenever allowed by language rules. So, the last use of a local (when it becomes unreachable), is also a last time of guaranteed referencing of it from the stack, and it's referenced usually as long as some next operation replaces its stack space with another reference (in simple methods though, it may not happen at all before method end). See JLS3 12.6.1 for details on objects reachability, and what optimizing transformations of a program are allowed. Short quote: "For example, a compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner." piotr |
| All times are GMT. The time now is 05:48 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.