Reputation: 68935
So on termination even if there were some memory leaks all the memory will be reclaimed by the OS(Please correct if I have mistaken)
.Even if it does not gracefully shutdown all the memory and resources would be freed?
Eclipse
. But the shutdown hook thread is not running.
Does terminating process in eclipse call Runtime.getRuntime().halt(status)
because AFAIK that terminated JVM abruptly and not execute shutdown hook?Lastly if I have my main code something like below -
public static void main(String args[]){
Runtime.getRuntime().addShutdownHook(new Thread(new ShutDownHook()));
System.out.println("Shutdown hook registered");
System.out.println("Before calling exit");
System.exit(0);
System.out.println("After exit");
}
why is After exit
not printed? When shutdown hook is in execution main thread must continue further execution and print After exit
?
Upvotes: 0
Views: 1897
Reputation: 279950
1) You are correct.
2) The Java process' memory will be reclaimed, but you might want to do other cleanup, like delete some temp files.
3) Let's go to the javadoc of Runtime#addShutdownHook(Thread)
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
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.
You would have to look into Eclipse's source code, but it would seem like Eclipse terminates the process rather than sending a System.exit(..)
or a sending a user interrupt. This probably goes over the JVM which therefore doesn't execute the shutdown hooks.
4) The shutdown hooks you add with Runtime#addShutdownHook(Thread)
are added to a static
IdentityHashMap
in the ApplicationShutdownHooks
. This class registers its own shutdown hook with the Shutdown
class in a static
initializer block shown below
static {
try {
Shutdown.add(1 /* shutdown hook invocation order */,
false /* not registered if shutdown in progress */,
new Runnable() {
public void run() {
runHooks();
}
}
);
hooks = new IdentityHashMap<>();
} catch (IllegalStateException e) {
// application shutdown hooks cannot be added if
// shutdown is in progress.
hooks = null;
}
}
The runHooks()
method is
static void runHooks() {
Collection<Thread> threads;
synchronized(ApplicationShutdownHooks.class) {
threads = hooks.keySet();
hooks = null;
}
for (Thread hook : threads) {
hook.start();
}
for (Thread hook : threads) {
try {
hook.join();
} catch (InterruptedException x) { }
}
}
So the current thread joins all the other ones.
When
System.exit(0);
gets called, somewhere down the line Shutdown.sequence()
gets called which invokes Shutdown.hooks()
implemented as
private static void runHooks() {
for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
try {
Runnable hook;
synchronized (lock) {
// acquire the lock to make sure the hook registered during
// shutdown is visible here.
currentRunningHook = i;
hook = hooks[i];
}
if (hook != null) hook.run();
} catch(Throwable t) {
if (t instanceof ThreadDeath) {
ThreadDeath td = (ThreadDeath)t;
throw td;
}
}
}
}
One of the Runnable
objects in hooks
is what I described above. It doesn't spawn a new Thread
, it does it concurrently with run()
.
Once Shutdown.sequence()
is done, the system really exits, so the final System.out.println()
doesn't execute.
Upvotes: 4