java shutdownhook

参考:http://blog.yohanliyanage.com/2010/10/know-the-jvm-2-shutdown-hooks/

java doc: http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

1、ShutdownHook在某些情况下不会运行

ShutdownHook从不不保证一定会运行。当JVM由于内部原因崩溃,或接收到操作系统发送的SIGKILL命令等,关闭钩子来不及运行JVM进程就已经退出。


2、ShutdownHook可能在运行过程中被中止

操作系统在关闭过程中,发送SIGTERM命令给JVM,如果JVM不能在一定的时间内结束,例如ShutdownHook执行时间过长等,那ShutdownHook就很有可能在执行过程中被中止。
所以ShutdownHook必须能快速执行完,避免会发生阻塞的IO操作或锁相关的操作。


3、当存在多个ShutdownHook时,JVM在执行的时候不保证顺序

在jdk1.5的Shutdown类中,可以看到ShutdownHook都保存在一个HashSet中,JVM退出时迭代整个HashSet并分别调用线程的start方法。并发执行,而不是添加时的顺序。


4、在JVM关闭过程中不能添加或者去除ShutdownHook

当JVM开始关闭,则不允许再进行ShutdownHook的添加和删除操作,否则抛出IllegalStateException,即不能在ShutdownHook中添加或去除ShutdownHook。


5、不能在ShutdownHook中调用System.exit()

当在ShutdownHook中调用System.exit(),不会停止ShutdownHook反而会卡住整个JVM,只能kill -9强制中止进程(jdk1.5进行了验证)。但可以调用Runtime.halt()。


6、ShutdownHook抛出的异常和其他普通异常一样,由Uncaught Exception Handler进行处理



7、如果创建匿名内部线程类作为ShutdownHook线程,则容易发生内存泄漏。

这个是开发中遇到的问题,工具函数以匿名内部类的方式创建了很多ShutdownHook,由于内部匿名类会持有外层类的引用,导致外层类对象也一直无法释放。


8、Eclipse中调试shutdownhook

Eclipse的红色的Terminate按钮是强制关闭程序,类似kill -9,没法调用shutdownhook;

变通方法起一个线程开启监听console输入,回车后,调用 System.exit(0);就会触发shutdownhook

private static class ExitThread extends Thread{
        
        public void run() {
            System.out.println("==============eclipse debug==================");
            System.out.println("press ENTER to call System.exit(0) ");  
            System.out.println("==============eclipse debug==================");
            try {  
                System.out.println(System.in.read());
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            System.exit(0);  
        }
    }




你可能感兴趣的:(ShutDownHook)