JAVA虚拟机关闭钩子(Shutdown Hook)

JDK Hook

提供了Java.Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在一下几种场景中被调用:

Registers a new virtual-machine shutdown hook.
The Java virtual machine shuts down in response to two kinds of events:

  • 程序正常退出 或调用 system.exit()方法

The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or

  • 终端使用Ctrl+C触发的中断或者系统登出(log off) 或者系统shotdown

The virtual machine is terminated in response to a user interrupt, such as typing ^C (Ctrl+C), or a system-wide event, such as user logoff or system shutdown.

A shutdown hook is simply an initialized but unstarted thread. 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. 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.

Once the shutdown sequence has begun it can be stopped only by invoking the halt method, which forcibly terminates the virtual machine.

Once the shutdown sequence has begun it is impossible to register a new shutdown hook or de-register a previously-registered hook. Attempting either of these operations will cause an IllegalStateException to be thrown.

Shutdown hooks run at a delicate time in the life cycle of a virtual machine and should therefore be coded defensively. They should, in particular, be written to be thread-safe and to avoid deadlocks insofar as possible. They should also not rely blindly upon services that may have registered their own shutdown hooks and therefore may themselves in the process of shutting down. Attempts to use other thread-based services such as the AWT event-dispatch thread, for example, may lead to deadlocks.

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. When the virtual machine is terminated due to user logoff or system shutdown the underlying operating system may only allow a fixed amount of time in which to shut down and exit. It is therefore inadvisable to attempt any user interaction or to perform a long-running computation in a shutdown hook.

Uncaught exceptions are handled in shutdown hooks just as in any other thread, by invoking the uncaughtException method of the thread's ThreadGroup object. The default implementation of this method prints the exception's stack trace to System.err and terminates the thread; it does not cause the virtual machine to exit or halt.

  • Kill pid (注:在使用kill -9 pid时,是不会被调用的)

In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The virtual machine may also abort if a native method goes awry by, for example, corrupting internal data structures or attempting to access nonexistent memory. If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.

JAVA DEMO

  • 正常退出
package com.sparrow.hook;

/**
 * Created by harryy on 2018/5/21.
 */
public class NormalExitHook {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Execute Hook.....");
            }
        }));
        System.out.println("do something");
    }
}
cd  /d/sparrow/sparrow-shell/sparrow-test/src/test/java/com/sparrow/hook
$ javac -encoding utf8 NormalExitHook.java

cd /d/sparrow/sparrow-shell/sparrow-test/src/test/java //注意一定要回到源码目录

java com.sparrow.hook.NormalExitHook
do something
Execute Hook.....

OOM

package com.sparrow.hook;

/**
 * Created by harry on 2018/5/21.
 * <p>
 * -Xmx20M
 */
public class OutOfMemoryHook {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Execute Hook.....");
            }
        }));
        byte[] b = new byte[500 * 1024 * 1024];
        //死循环保证不正常退出
        while (true){}
    }
}

cd  /d/sparrow/sparrow-shell/sparrow-test/src/test/java/com/sparrow/hook
$ javac -encoding utf8 OutOfMemoryHook.java

cd /d/sparrow/sparrow-shell/sparrow-test/src/test/java
java -Xmx20M com.sparrow.hook.OutOfMemoryHook
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at com.sparrow.hook.OutOfMemoryHook.main(OutOfMemoryHook.java:16)
Execute Hook.....

Uncatch Exception

package com.sparrow.hook;

/**
 * Created by harry on 2018/5/21.
 */
public class UncacheExceptionHook {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Execute Hook.....");
            }
        }));
        //运行时异常
        int i=1/0;
        //死循环保证不正常退出
        while (true) {
        }
    }
}
cd  /d/sparrow/sparrow-shell/sparrow-test/src/test/java/com/sparrow/hook
$ javac -encoding utf8 UncatchExceptionHook.java
cd /d/sparrow/sparrow-shell/sparrow-test/src/test/java
$ java com.sparrow.hook.UncatchExceptionHook
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at com.sparrow.hook.UncatchExceptionHook.main(UncatchExceptionHook.java:15)
Execute Hook.....

CTRL+C

package com.sparrow.hook;

/**
 * Created by harry on 2018/5/21.
 * <p>
 * JAVA_HOME:D:\Java\jdk1.8.0_91
 * <p>
 * CLASSPATH:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
 */
public class CtrlCHook {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Execute Hook.....");
            }
        }));
        System.out.println("do something");
        System.out.println("press ctrl+c");
        //死循环保证不正常退出
        while (true) {
        }
    }
}

cd  /d/sparrow/sparrow-shell/sparrow-test/src/test/java/com/sparrow/hook
$ javac -encoding utf8 CtrlCHook.java
cd /d/sparrow/sparrow-shell/sparrow-test/src/test/java
$ java com.sparrow.hook.CtrlCHook
do something
press ctrl+c
Execute Hook.....

KILL


$ kill -l

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGEMT       8) SIGFPE       9) SIGKILL     10) SIGBUS
11) SIGSEGV     12) SIGSYS      13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGURG      17) SIGSTOP     18) SIGTSTP     19) SIGCONT     20) SIGCHLD
21) SIGTTIN     22) SIGTTOU     23) SIGIO       24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGPWR      30) SIGUSR1
31) SIGUSR2     32) SIGRTMIN    33) SIGRTMIN+1  34) SIGRTMIN+2  35) SIGRTMIN+3
36) SIGRTMIN+4  37) SIGRTMIN+5  38) SIGRTMIN+6  39) SIGRTMIN+7  40) SIGRTMIN+8
41) SIGRTMIN+9  42) SIGRTMIN+10 43) SIGRTMIN+11 44) SIGRTMIN+12 45) SIGRTMIN+13
46) SIGRTMIN+14 47) SIGRTMIN+15 48) SIGRTMIN+16 49) SIGRTMAX-15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9
56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4
61) SIGRTMAX-3  62) SIGRTMAX-2  63) SIGRTMAX-1  64) SIGRTMAX

package com.sparrow.hook;

/**
 * Created by harry on 2018/5/21.
 */
public class KillHook {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("execute Hook.....");
            }
        }));
        System.out.println("do something");
        //死循环保证不正常退出
        while (true) {
        }
    }
}

cd  /d/sparrow/sparrow-shell/sparrow-test/src/test/java/com/sparrow/hook
$ javac -encoding utf8 KillHook.java
cd /d/sparrow/sparrow-shell/sparrow-test/src/test/java
$ java com.sparrow.hook.KillHook
do something
$ ps aux |grep java
     9372    8888    9372       6436  pty0      197611 18:47:47 /c/Program Files/Java/jdk1.8.0_121/bin/java
     
kill -SIGHUP 9372

$ java com.sparrow.hook.KillHook
do something
Hangup

KILL 指令,并未执行hook,其他sign 测试,感兴越的朋友可以自行测试

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,324评论 0 10
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,491评论 0 23
  • 破旧的窝棚四面相通,海风吹着仅挂在窝棚边上的一块黑漆漆的有多处漏洞的破布。这是唯一一片可以遮风的布了,老人睡着了,...
    青木微风阅读 1,726评论 0 0
  • 刚刚过完五一劳动节,放飞的心估计还没收回来,上学时间也有所变动。。。。 早上早早的起床,还一直停留...
    小呆呆的烦恼阅读 143评论 0 0
  • 昨天听说一个同事买了保险,保障未来有重大疾病的所有保障。3年6万元对一个人来说并不是太多的钱,而是在年纪尚轻就去对...
    蓝色孤枫阅读 153评论 0 0