精华内容
下载资源
问答
  • Java 钩子程序

    2021-03-09 06:07:17
    简介触发的时机有:当所有的非deamon线程(守护线程)结束, 或者调用了Systrem.exit()方法 而导致的程序正常的退出JVM收到需要关闭自己的信号(比如SIGINT、SIGTERM等,但像SIGKILL,JVM就没有机会去处理了),也或者...

    简介

    触发的时机有:

    当所有的非deamon线程(守护线程)结束, 或者调用了Systrem.exit()方法 而导致的程序正常的退出

    JVM收到需要关闭自己的信号(比如SIGINT、SIGTERM等,但像SIGKILL,JVM就没有机会去处理了),也或者发生如系统关闭这种不可阻挡的事件。

    对于addShutdownHook中的钩子代码,也是有一些要注意的地方,下面列举几点:

    关闭钩子可以注册多个,在关闭JVM时就会起多个线程来运行钩子。通常来说,一个钩子就足够了,但如果需要启用多个钩子,就需要注意并发带来的问题。

    钩子里也要注意对异常的处理,如果不幸抛出了异常,那么钩子的执行序列就会被终止。

    在钩子运行期间,工作线程也在运行,需要考虑到工作线程是否会对钩子的执行带来影响

    钩子里的代码尽可能简洁,否则当像系统关闭等情景可能钩子来不及运行完JVM就被退出了。

    信号触发

    使信号触发JVM的钩子程序

    public class HookTest {

    public static void main(String[] args) {

    Runtime.getRuntime().addShutdownHook(new Hook());

    while(true){}

    }

    static class Hook extends Thread{

    @Override

    public void run() {

    System.out.println("Hook execute!!!");

    }

    }

    }

    运行钩子程序

    nohup java HookTest &

    关闭程序

    kill HookTest_PID

    我们可以在nohup程序中看到Hook execute!!!输出

    我从JVMs and kill signals看到一篇博客, 这个上面总结了哪些信号会导致JVM运行Hook

    signal shutdown runs hook exit code comment

    default (15) yes yes 143 SIGTERM is the default unix kill signal

    0 no - -

    1 (SIGHUP) yes yes 129

    2 (SIGINT) yes yes 130 SIGINT is the signal sent on ^C

    3 (SIGQUIT) no - - 触发 JVM dump threads / stack-traces

    4 (SIGILL) yes no 134 触发 JVM 输出一个 core dump 文件, 同时abort on trap 6

    5 yes no 133 Makes the JVM exit with "Trace/BPT trap: 5"

    6 (SIGABRT) yes no 134 Makes the JVM exit with "Abort trap: 6"

    7 yes no 135 Makes the JVM exit with "EMT trap: 7"

    8 (SIGFPE) yes no 134 Makes the JVM write a core dump and abort on trap 6

    9 (SIGKILL) yes no 137 The JVM is forcibly killed (exits with "Killed: 9")

    10 (SIGBUS) yes no 134 Emulates a "Bus Error"

    11 (SIGSEGV) yes no 134 Emulates a "Segmentation fault"

    12 yes no 140 Makes the JVM exit with "Bad system call: 12"

    13 no - -

    14 yes no 142 Makes the JVM exit with "Alarm clock: 14"

    15 (SIGTERM) yes yes 143 This is the default unix kill signal

    16 no - -

    17 no - 145 Stops the application (sends it to the background), same as ^Z

    18 no - 146 Stops the application (sends it to the background), same as ^Z

    19 no - -

    20 no - -

    21 no - 149 Stops the application (sends it to the background), same as ^Z

    22 no - 150 Stops the application (sends it to the background), same as ^Z

    23 no - -

    24 yes no 152 Makes the JVM exit with "Cputime limit exceeded: 24"

    25 no - -

    26 yes no 154 Makes the JVM exit with "Virtual timer expired: 26"

    27 yes no 155 Makes the JVM exit with "Profiling timer expired: 27"

    28 no - -

    29 no - -

    30 yes no 158 Makes the JVM exit with "User defined signal 1: 30"

    31 yes no 134 Makes the JVM exit on Segmentation fault

    内存溢出触发

    测试JVM栈溢出后调用钩子程序

    public class HookTest {

    public static void main(String[] args) {

    Runtime.getRuntime().addShutdownHook(new Hook());

    exec();

    }

    public static void exec() {

    exec();

    }

    static class Hook extends Thread{

    @Override

    public void run() {

    System.out.println("Hook execute!!!");

    }

    }

    }

    运行后输出为

    D:\testOOM>java HookTest

    Exception in thread "main" java.lang.StackOverflowError

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    ...

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    at HookTest.exec(HookTest.java:9)

    Hook execute!!!

    D:\testOOM>

    为了测试在更加复杂的环境下, Hook的使用情况, 看下面的测试代码

    import java.time.LocalDateTime;

    import java.util.HashMap;

    import java.util.Map;

    import java.util.concurrent.TimeUnit;

    public class HookTest {

    private static Map cache = new HashMap<>();

    public static void main(String[] args) {

    cache.put("abc", "abc");

    Runtime.getRuntime().addShutdownHook(new Hook());

    byte[] bytes = new byte[1024 * 1024 *1024 * 1024];

    }

    static class Hook extends Thread{

    @Override

    public void run() {

    for (int i = 0; i < 100; i++) {

    System.out.println(LocalDateTime.now());

    System.out.println(" freeMemory : " + Runtime.getRuntime().freeMemory());

    System.out.println(" maxMemory : " + Runtime.getRuntime().maxMemory());

    System.out.println(" totalMemory : " + Runtime.getRuntime().totalMemory());

    System.out.println(" currentThread name : " + Thread.currentThread().getName());

    System.out.println(" cache size : " + cache.size());

    cache.put(LocalDateTime.now().toString(), LocalDateTime.now().toString());

    try {

    TimeUnit.SECONDS.sleep(1);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    }

    }

    运行后的输出结果为

    ζ java HookTest

    2016-07-09T16:12:12.479

    freeMemory : 155922512

    maxMemory : 2375024640

    totalMemory : 160956416

    currentThread name : Thread-0

    cache size : 1

    2016-07-09T16:12:13.480

    freeMemory : 155922512

    maxMemory : 2375024640

    totalMemory : 160956416

    currentThread name : Thread-0

    cache size : 2

    2016-07-09T16:12:14.480

    freeMemory : 155922512

    maxMemory : 2375024640

    totalMemory : 160956416

    currentThread name : Thread-0

    cache size : 3

    2016-07-09T16:12:15.480

    freeMemory : 155922512

    maxMemory : 2375024640

    totalMemory : 160956416

    currentThread name : Thread-0

    cache size : 4

    ...

    正常结束触发

    测试程序正常结束后也会调用钩子程序

    public class HookTest {

    public static void main(String[] args) {

    Runtime.getRuntime().addShutdownHook(new Hook());

    }

    static class Hook extends Thread{

    @Override

    public void run() {

    System.out.println("Hook execute!!!");

    }

    }

    }

    运行结果为

    D:\testOOM>java HookTest

    Hook execute!!!

    D:\testOOM>

    调用exit()触发

    public class HookTest {

    public static void main(String[] args) {

    Runtime.getRuntime().addShutdownHook(new Hook());

    System.exit(0);

    System.out.println("Main over");

    }

    static class Hook extends Thread{

    @Override

    public void run() {

    System.out.println("Hook execute!!!");

    }

    }

    }

    运行结果为

    D:\testOOM>java HookTest

    Hook execute!!!

    D:\testOOM>

    不被触发

    再google上找到了一篇这样的文章Know the JVM Series: Shutdown Hooks里面介绍了钩子程序在什么情况下不会执行

    尽管上面列举出了N多触发钩子程序的示例, 但是并不保证这个钩子程序总是能被触发执行的, 例如

    JVM内部发生错误, 可能还没有来得及触发钩子程序, JVM就挂掉了(JVM 发生内部错误, 有没有日志呢?)

    还有上面我们给出的那个信号表, 如果操作系统发送出上面的信号的话, 同样的, JVM没有执行钩子程序就退出了

    还有调用Runime.halt()函数也不会执行钩子程序

    还有一种情况是, 当操作系统向进程发送一个SIGTERM信号之后, 如果进程没有在指定的时间之内关闭, 那么操作系统会强制将该进程杀掉, 如此一来钩子程序也不会得到完整的执行(因为钩子程序可能执行到一半就被操作系统杀死了). 因此不管是这篇文章还是JDK API都推荐不要在钩子程序里写复杂的业务逻辑, 避免产生死锁或者产生长时间的IO操作, 尽可能快地让钩子程序执行完毕.

    Will shutdown hooks be run if the VM crashes?

    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.

    哎,, 怎么着才能监控JVM挂掉的信息呢?

    展开全文
  • 需求:想要在程序退出的时候,能够进行一些文件的清理,能够进行一些资源的释放,一些运行时的数据的保存。还有一个需求是在退出的时候,需要将阻塞队列里边的数据,处理完再退出。 说明:springboot项目 ...

     需求:想要在程序退出的时候,能够进行一些文件的清理,能够进行一些资源的释放,一些运行时的数据的保存。还有一个需求是在退出的时候,需要将阻塞队列里边的数据,处理完再退出。 

     

      说明:springboot 项目

                 关闭程序的时候,只能使用 kill  pid 的方式终止程序,不能使用 kill  -9  pid 的方式。因为 kill -9 的方式,会直接退出。这个这里不过多的赘述了。

     

       # # 解决方案

      在 application 启动类里边添加如下的代码,其中application启动类就是我们创建springboot 项目的时候就会有的类。然后需要执行的代码放在先撤线程里边

     

    // 定义关闭线程
    Thread shutdownThread = new Thread() {
        public void run() {
            System.out.println("shutdownThread...");
        }
    };
    Runtime.getRuntime().addShutdownHook(shutdownThread);

     

     ~ ps

      写在最后:其实我最想,在 kill  -9  pid 的时候,也能够触发钩子程序。 但是我目前还做不到,因为系统命令 kill -9  就是直接退出,钩子程序也不会执行了。 我见过的能够平滑退出的有 elasticsearch ,它在使用  kill -9 的时候,仍然能够执行一些内容。

     

     

    展开全文
  • 这次做一个比较有意思的实验,我们知道当一个程序如果抛异常了其程序肯定会挂掉,那有木有可能在程序异常退出时能执行一段咱们自己的代码,比如说服务器在异常退出时需要做一些额外的资源清理,像这种场景就正好是...

    这次做一个比较有意思的实验,我们知道当一个程序如果抛异常了其程序肯定会挂掉,那有木有可能在程序异常退出时能执行一段咱们自己的代码,比如说服务器在异常退出时需要做一些额外的资源清理,像这种场景就正好是这里有实验的,下面开始,因为这个实验用shell命令演示会比较方便,所以建议实验是在linux、mac系统下,windows上木有这么方便。

    首先新建一个java类:

    38c0336966bbc5b3fbdaf3dc243dc325.png

    8e4e7ceecab1db929072fd9d23c1c2ec.png

    比较简单,就是有一个死循环来模拟程序在工作,编译运行:

    d725ea5eca9482490f292c1d6e3d7bde.png

    咱们可以将这个程序放到后台去运行,不至于阻塞终端:

    962d543bd453339cdaf75f29e444e566.png

    b63f6f5a4920527ac1c0b6c1777d5343.png

    然后此时的运行结果就都输出到了"nohup.out"这个日志文件了,可以通过如下命令去查看:

    93217aade4aebeeb911faa28c5dcc2d9.png

    dd3aea3d77c0d1251a51ce8d2dd2577d.png

    那如果此时用kill命令将咱们这个程序给杀掉,杀掉之后咱们目前程序是没有任何处理的,如下:

    925f0b219716d2d7d3800503bd6ab8f4.png

    而如果是程序出现了异常那咱们的程序也就直接挂掉了,咱们来改一下程序:

    2a18318a206ba15571505149c06502db.png

    编译运行:

    a51e34eb15f71b59cc50b1843ce65987.png

    接下来给程序加入一个钩子,当进程死掉之后可以执行咱们的一段逻辑,具体做法如下:

    f752d1b20d668d3f1c5f6b55f9d2395b.png

    编译运行:

    52cffd7417d62fb6b9217588ab6d1759.gif

    很显然这次当程序抛异常导致程序挂掉之后就正常执行了咱们预期的程序,这也就是钩子程序的作用,那下面再来试验一下如果用kill命令手动去杀那依然可以执行钩子程序么,先将异常给注释掉:

    fd63be418d6dd65e0ea451c9a8c73cfe.png

    再来编译运行:

    d8aceea622b388b07f49faa56138f6e3.gif

    嗯~~正常被执行了,但是kill -9就不一样了,下面演示一下:

    3cc14cf5e2b8f57d8cd65faee095fe15.gif

    很显然这次程序就直接挂掉了,因为kill -9属于强杀,对于这种情况咱们的钩子程序是不管用的,所以对于服务器的管理人员杀掉程序时一般是非常忌讳用kill -9的。

    展开全文
  • java中addShutdownHook钩子程序用途

    千次阅读 2017-03-15 21:08:38
    1.钩子程序执行时机: 当程序正常退出,系统调用 System.exit方法或虚拟机被关闭时才会执行添加的shutdownHook线程。其中shutdownHook是一个已初始化但并不有启动的线程,当jvm关闭的时候,会执行系统中已经设置的...

    通过我们的程序中运行完之后都会进行一些清理工作,比如关闭数据库资源,同步等操作。这时我们的钩子函数addShutdownHook有了用武之地。

    1.钩子程序执行时机:

    当程序正常退出,系统调用 System.exit方法或虚拟机被关闭时才会执行添加的shutdownHook线程。其中shutdownHook是一个已初始化但并不有启动的线程,当jvm关闭的时候,会执行系统中已经设置的所有通过方法addShutdownHook添加的钩子,当系统执行完这些钩子后,jvm才会关闭。所以可通过这些钩子在jvm关闭的时候进行内存清理、资源回收等工作。 
    2.用法

    Runtime.getRuntime().addShutdownHook(Thread thread)

    这里我们需要将一个线程对象传入,作为钩子程序的实现代码。本质上就是在jvm关闭时,执行一个线程。

    3.实战

    public class Client{
    public void test1(){
    	System.out.println("startting working......");
    	Runtime.getRuntime().addShutdownHook(new Thread(){
    		@Override
    		public void run() {
    			System.out.println("执行钩子线程");
    		}
    	});
    	System.out.println("program endding");
    }
    }
    执行结果:
    startting working......
    program endding
    执行钩子线程
    
    果然钩子线程是在主程序执行完毕之后才开始执行。

    展开全文
  • Java 多线程之 Hook (钩子) 线程
  • Java钩子函数的应用

    2021-06-20 09:47:37
    文章目录Hook概念Hook基本用法项目解决方法 ... 那么就需要一种办法,在服务端关闭之前自动向 Nacos 注销服务。但是有一个问题,不知道什么时候服务器会...这时,我们就需要钩子,由此引出本文。 Hook概念 Hook翻译成
  • 我在jBuilder里面用swing实现的该程序,其实很简单,就是调用了里面库文件的两个监听事件,当程序失去焦点以后仍然可以显示出当前鼠标的坐标。之所以上传是因为不少人可能对swt extension并不熟悉,导致自己用JNI...
  • java鼠标钩子 运行程序 显示鼠标位置
  • 以前在开发时只知道依靠数据库事务来保证...这时我们可以依靠java提供的一个工具方法:java.lang.Runtime.addShutdownHook(Thread hook)addShutdownHook方法可以加入一个钩子,在程序退出时触发该钩子。(退出是指ctr...
  • 本篇要带来的是java中的关闭钩子,它是jvm中的一种使用,主要是用来对其进行关闭的。那么java关闭钩子的使用注意点,想必大家还没有学习过,下面我们就来进行详细的介绍。1、说明关闭钩子本质上是一个线程(也称为...
  • 以前在开发时只知道依靠数据库事务来保证...这时我们可以依靠java提供的一个工具方法:java.lang.Runtime.addShutdownHook(Thread hook)addShutdownHook方法可以加入一个钩子,在程序退出时触发该钩子。(退出是指ctr...
  • 用途1应用程序正常退出,在退出时执行特定的业务逻辑,或者关闭资源等操作。2虚拟机非正常退出,比如用户按下ctrl+c、OutofMemory宕机、操作系统关闭等。在退出时执行必要的挽救措施。我的案例场景:后台服务代码...
  • 需要到http://java.net/projects/jna/downloads下载 jna.jar 和 platform.jar(参考http://my.oschina.net/penngo/blog/12356):1.[代码][Java]代码package jna_test;import com.sun.jna.platform.win32.*;import ...
  • 当jvm进程退出的时候,或者受到了系统的中断信号,hook线程就会启动,一个线程可以注入多个钩子,这是一个实例:import java.io.IOException;import java.util.concurrent.TimeUnit;public class HookTest {public ...
  • JAVA 的世界里遨游,如果能拥有一...a)如何让 Java 程序实现优雅停服?有思想才是硬道理!b)addShutdownHook 的使用场景?会用才是王道!c)addShutdownHook 钩子函数到底是个啥?刨根问底!1. 如何让 Java 程序实...
  • java 键盘钩子程序

    2010-11-19 15:52:17
    http://d.download.csdn.net/down/1720478/qwe852012
  • java-Runtime钩子回调

    2021-03-16 20:03:43
    java-Runtime钩子回调2019年12月06日阅读数:8这篇文章主要向大家介绍java-Runtime钩子回调,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。----------~开篇分享一句话:【纸上得来终觉浅,...
  • 一、接收信号 1、在Linux中执行kill -l查看信号,共有...二、注册钩子 Runtime.getRuntime().addShutdownHook(new Thread("xx-shutdown-hook") { @Override public void run() { //资源释放动作 } });  
  • Java程序中可以通过添加关闭钩子,实现在程序退出时关闭资源、平滑退出的功能。 同理关闭钩子是removeShutdownHook 使用Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在以下...
  • java的鼠标键盘钩子程序swt实现

    热门讨论 2009-04-24 16:35:26
    java的鼠标键盘钩子程序swt实现,目前能找到的比较方现成的实现,用起来也比较方便。
  • Java HOOK - 钩子机制扫盲

    万次阅读 2017-07-25 14:14:46
    一、什么是HOOK(钩子)   对于Windows系统,它是建立在事件驱动机制上的,说白了就是整个系统都是通过消息传递实现的。hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往...
  • 在开发中,遇到一个问题。我们每次重启一个应用的时候,总会导致一些正在执行的任务因为机器突然死掉,如果不对这种正在执行的任务记录,处理的话,这些任务就消失了。...import java.util.concurrent.TimeUnit...
  •   // 定义关闭线程 Thread shutdownThread = new Thread() { public void run() { System.out.println("shutdownThread...");...addShutdownHook方法可以加入一个钩子,在程序退出时触发该钩子
  • Runtime.getRuntime().addShutdownHook(shutdownHook);这个方法的含义说明:这个方法的意思就是在jvm中增加一个关闭的钩子,当jvm关闭的时候,会执行系统中已经设置的所有通过方法...用途1应用程序正常退出,在退出...
  • java-钩子线程

    千次阅读 2017-09-11 17:26:07
    在线上Java程序中经常遇到进程程挂掉,一些...  JDK在1.3之后提供了Java Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在以下几种场景被调用: 1)程序正常退出 2)使用
  • java鼠标钩子实现

    2010-12-17 00:54:13
    http://blog.csdn.net/penngo/archive/2010/12/17/6081283.aspx的附件运行程序
  • 在线上Java程序中经常遇到进程程挂掉,一些... JDK在1.3之后提供了Java Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在以下几种场景被调用: 1)程序正常退出2)使用Sys
  • JAVA-JVM的钩子函数

    2020-08-28 14:03:26
    当jvm进程退出的时候,或者受到了系统的中断信号,hook线程就会启动,一个线程可以注入多个钩子,这是一个实例: import java.io.IOException; import java.util.concurrent.TimeUnit; public class HookTest { ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,713
精华内容 7,885
关键字:

java钩子程序

java 订阅