I just fail to understand why must one use Runtime.addShutdownHook. If you want to do some cleanup when the jvm exits, why not just overload the finalize method of the daemon class. What is the advantage of using shutdown hook over finalize method.
Also there is a deprecated function runFinalizersOnExit. If I set it to false, I believe finalizers won't run. This contradicts the java guarantee that finalizers always run before garbage collections.
Regarding your query
If you want to do some cleanup when the jvm exits, why not just overload the finalize method of the daemon class
I have found good information from this article
finalize()
is called before Garbage collector reclaim the Object. JVM does not guaranty when this method will be invoked.
finalize()
gets called only once by GC thread if object revives itself from finalize method than finalize will not be called again.
In your application, you may have some live objects, on which garbage collection is never invoked.
Any Exception is thrown by finalize method is ignored by GC thread
System.runFinalization(true)
and Runtime.getRuntime().runFinalization(true)
methods increase the probability of invoking finalize()
method but now these two methods have been deprecated. These methods are very dangerous due to lack of thread safety and possible deadlock creation.
Coming back to shutdownHooks, as per oracle documentation
public void addShutdownHook(Thread hook) Registers a new virtual-machine shutdown hook.
The Java virtual machine shuts down in response to two kinds of events:
But even oracle documentation quoteed that
Shutdown hooks should also finish their work quickly. When a program invokes exit the expectation is that the virtual machine will promptly shut down and exit.
In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly
Considering drawbacks of the both these approaches, you should follow below approach
Do not depend on finalize()
or shutdown hooks
to release critical resources in your application.
use try{} catch{} finally{}
blocks appropriately and release critical resources in finally(}
block. During release of resources in finally{}
block, catch Exception
and Throwable
.
There is no guarantee that a finalizer will ever run. finalize()
is called when the object is garbage collected. But the garbage collector may not collect anything when the program runs.
Shutdown hooks by contrast are run when the jvm exits normally. so even that isn't 100% guarantee either but it's pretty close. There are only a few edge cases where a shutdown hook doesn't run.
EDIT I looked up the edge cases where a shutdown hook is not executed
Shutdown hook IS executed:
Shutdown hook IS NOT executed:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With