finalize() not guaranteed to be called -- ever

P

Paul J. Lucas

Ingo R. Homann said:
I don't know, but in newer Versions there is a Shutdown-Hook-mechanism
for dealing with that.

I know, and that's not what I'm asking about. Why should *I*
have to add a shutdown hook to call System.runFinalizers() ? I
want to know if the JVM will *guarantee* that all finalizers
will *automatically* be executed prior to JVM shutdown

- Paul
 
E

Eric Sosman

Paul said:
I know, and that's not what I'm asking about. Why should *I*
have to add a shutdown hook to call System.runFinalizers() ? I
want to know if the JVM will *guarantee* that all finalizers
will *automatically* be executed prior to JVM shutdown

Ingo seems to be saying something slightly different:
not that you should use a shutdown hook to run finalizers,
but that you should use it for the cleanup you're now (it
seems) trying to do in the finalizers.

FWIW, the gurus (I am not one) seem to be unanimous in
warning against using finalizers as destructors. Eckel puts
it this way: Garbage collection is about memory, finalization
is an aspect of garbage collection, therefore finalization is
about memory and anything that isn't about memory is out of
place in a finalizer. Bloch writes at length about the dangers
of finalization, and recounts the tale of an OutOfMemoryError
that was caused by relying on finalizers -- not by bug-ridden
finalizers, mind you, but simply by reliance on them. Add to
this some of the scarier passages where the Javadoc explains
why System.runFinalizersOnExit() is deprecated (sounds like a
hint, doesn't it?), and I think there are enough bad omens to
make you consider other avenues ...
 
P

Patricia Shanahan

Joan said:
My book says that if you execute "System.exit(0);" that it does an exit
without doing anything else.

Books often skip details and advanced information to keep down the size
and focus on the basics. Once you have the basic concepts, use the API
Javadocs and Java Language Specification to fill in missing details.

The System.exit documentation indicates that System.exit(n) is
effectively equivalent to Runtime.getRuntime().exit(n).

The documentation for exit in Runtime says:

"The virtual machine's shutdown sequence consists of two phases. In the
first phase all registered shutdown hooks, if any, are started in some
unspecified order and allowed to run concurrently until they finish. In
the second phase all uninvoked finalizers are run if
finalization-on-exit has been enabled. Once this is done the virtual
machine halts."

It is also described as throwing "SecurityException - If a security
manager is present and its checkExit method does not permit exiting with
the specified status" so the exit is conditional.

This is the same as "exit without doing anything else" in many cases,
but not all. This type of simplification is typical of many books, and
harmless as long as readers understand that the book is not telling the
whole story, and know where to look for more data.

Patricia
 
A

Andrea Desole

Paul said:
According to:

http://www.unix.org.ua/orelly/java-ent/jnut/ch03_03.htm

that says in part:

The Java interpreter can exit without garbage collecting
all outstanding objects, so some finalizers may never be
invoked.

Is this still true in Java 1.4 and later?

Yes. Well, not completely. If you look at:

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html#19152

you will see:

A program can specify that all finalizers that have not been
automatically invoked are to be run before the virtual machine exits.
This is done by invoking the method runFinalizersOnExit of the class
System with the argument true.4 By default finalizers are not run on
exit. Once running finalizers on exit has been enabled it may be
disabled by invoking runFinalizersOnExit with the argument false. An
invocation of the runFinalizersOnExit method is permitted only if the
caller is allowed to exit and is otherwise rejected by the security manager.
 
I

Ingo R. Homann

Hi,

Eric said:
Ingo seems to be saying something slightly different:
not that you should use a shutdown hook to run finalizers,
but that you should use it for the cleanup you're now (it
seems) trying to do in the finalizers.

FWIW, the gurus (I am not one) seem to be unanimous in
warning against using finalizers as destructors...

Well, in my experience, finalizers work very well if you only use them
for cleaning up and not doing something dirty like the following:

class X {
static X x;
void finalize() {
x=this;
}
}

Anyhow, although finalizers are working perfectly in practise, It is
correct that theoretically you cant rely on them.
So, I would not rely on them when programming a control application for
a nuclear power plant.

Ciao,
Ingo
 
P

Paul J. Lucas

Doug Pardee said:
No, it won't guarantee that.

Then what's the point of a finalizer? The JVM *should*
guarantee that just like C++ guarantees that all destructors
for all locally-scoped and static objects *will* be called
prior to program termination (unless you do something drastic
like call abort()).

- Paul
 
P

Paul J. Lucas

Andrea Desole said:
Yes. Well, not completely. If you look at:

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html#19152

you will see:

A program can specify that all finalizers that have not been
automatically invoked are to be run before the virtual machine exits.
This is done by invoking the method runFinalizersOnExit of the class
System with the argument true.

It also says:

This method is inherently unsafe. It may result in
finalizers being called on live objects while other
threads are concurrently manipulating those objects,
resulting in erratic behavior or deadlock.

So why don't they just fix runFinalizersOnExit() so it's not
unsafe? If you first killed off all threads but the one doing
the shutting down, then it would be impossible to deadlock.
All the threads have to be killed anyway.

- Paul
 
A

Andrea Desole

Paul said:
It also says:

This method is inherently unsafe. It may result in
finalizers being called on live objects while other
threads are concurrently manipulating those objects,
resulting in erratic behavior or deadlock.

yes, that's in the Javadoc
So why don't they just fix runFinalizersOnExit() so it's not
unsafe? If you first killed off all threads but the one doing
the shutting down, then it would be impossible to deadlock.

Yes, it sounds logical; I don't know why it's not different.
But, if you are just looking for a clean solution to free your resources
when the application terminates, I think Ingo gave you a good answer.
 
T

Thomas Hawtin

Paul said:
It also says:

This method is inherently unsafe. It may result in
finalizers being called on live objects while other
threads are concurrently manipulating those objects,
resulting in erratic behavior or deadlock.

So why don't they just fix runFinalizersOnExit() so it's not
unsafe? If you first killed off all threads but the one doing

The word "inherently" in there is a clue.
the shutting down, then it would be impossible to deadlock.
All the threads have to be killed anyway.

Two reasons spring to mind:
o Finalisers can be dependent upon other threads.
o Threads aren't killed until the plug is pulled on the JVM. If you
kill a thread that holds locks then you are in trouble. See Thread.kill.

Any reasonable operating system will clear up process resources when
they exit. Persistent resource can be cleared up through a shutdown hook.

Tom Hawtin
 
T

Thomas Hawtin

Paul said:
Then what's the point of a finalizer? The JVM *should*

To clear up resources from buggy application code. They can be a useful
way to free up memory without having a reference queue in some
circumstances.

But most finaliser use is down to bad programming.
guarantee that just like C++ guarantees that all destructors
for all locally-scoped and static objects *will* be called
prior to program termination (unless you do something drastic
like call abort()).

Finalisers are not destructors.

Java is not C++.

Tom Hawtin
 
E

Eric Sosman

Thomas said:
To clear up resources from buggy application code. They can be a useful
way to free up memory without having a reference queue in some
circumstances.

Code needn't be buggy to require finalization. For
example, a Java object that's backed by a non-Java entity
via JNI could use finalize() to tell its counterpart it's
no longer needed.
But most finaliser use is down to bad programming.

That may well be true ;-)
 
J

Joan

Anyhow, although finalizers are working perfectly in practise,
It is correct that theoretically you cant rely on them.
So, I would not rely on them when programming a control
application for a nuclear power plant.

As if that is on your job list.
 
T

Thomas Hawtin

Eric said:
Code needn't be buggy to require finalization. For
example, a Java object that's backed by a non-Java entity
via JNI could use finalize() to tell its counterpart it's
no longer needed.

Then the Java object should have some kind of dispose method.

Tom Hawtin
 
M

Monique Y. Mudama

Books often skip details and advanced information to keep down the
size and focus on the basics. Once you have the basic concepts, use
the API Javadocs and Java Language Specification to fill in missing
details.

Is this the spot where Thinking in Java is once again mentioned as a
great book that does actually address this type of information?

(Disclaimer: I haven't checked to see if this *exact* tidbit is in the
book)
 
A

Andrea Desole

Thomas said:
Two reasons spring to mind:
o Finalisers can be dependent upon other threads.
o Threads aren't killed until the plug is pulled on the JVM. If you
kill a thread that holds locks then you are in trouble. See Thread.kill.

but, if you exit the program "cleanly" (that is, without calling
exit()), shouldn't the finalizers be called after all the threads are
terminated?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top