Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shutdown hook vs finalizer method

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.

like image 627
S Kr Avatar asked Dec 29 '13 19:12

S Kr


Video Answer


2 Answers

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

  1. finalize() is called before Garbage collector reclaim the Object. JVM does not guaranty when this method will be invoked.

  2. finalize() gets called only once by GC thread if object revives itself from finalize method than finalize will not be called again.

  3. In your application, you may have some live objects, on which garbage collection is never invoked.

  4. Any Exception is thrown by finalize method is ignored by GC thread

  5. 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:

  1. The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
  2. The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
  3. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled.
  4. Finally, the virtual machine will halt. Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if shutdown was initiated by invoking the exit method.

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

  1. Do not depend on finalize() or shutdown hooks to release critical resources in your application.

  2. use try{} catch{} finally{} blocks appropriately and release critical resources in finally(} block. During release of resources in finally{} block, catch Exception and Throwable.

like image 139
Ravindra babu Avatar answered Oct 01 '22 15:10

Ravindra babu


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:

  • When all of JVM threads have completed execution
  • Because of call to System.exit()
  • Because user hit CNTRL-C
  • System level shutdown or User Log-Off

Shutdown hook IS NOT executed:

  • If the VM crashes due to an error in native code then no guarantee can be made about whether or not the hooks will be run.
  • If JVM is killed using -kill command on Linux or Terminate Process on windows, then JVM exits instantly
like image 22
dkatzel Avatar answered Oct 01 '22 15:10

dkatzel