简体   繁体   中英

Queries regarding Shutdown hook

  1. If i have gotten it correctly each java process is associated with a separate instance of JVM and each instance of JVM is provided with a Heap memory by the OS which is also recollected by the OS on JVM termination. 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) .
  2. In case point number 1 is true why do we have to use shutdown hooks. After googling everything mainly suggests to free all the resources and graceful shutdown. Even if it does not gracefully shutdown all the memory and resources would be freed?
  3. I wrote a simple shutdown hook. In my main thread I am running an infinite loop and then terminating the process using terminate button in 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?
  4. 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 ?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM