有什么办法可以在jvm进程被杀死时执行一些java代码吗?

时间:2014-05-06 06:34:48

标签: java jvm

我们希望在JVM手动终止时退出之前执行一些java代码或shell代码。我们的应用程序没有在容器中运行。我们需要使用Java代码本身或某些命令行工具自动监视它。

3 个答案:

答案 0 :(得分:11)

您可以使用Runtime.getRuntime().addShutdownHook()添加关机挂钩。这样的关闭挂钩由JVM运行,一旦JVM'流程终止。但请注意,并非总是如此。 JVM可能会在有机会触发其关闭挂钩之前被杀死。这在javadoc中提到:

  

在极少数情况下,虚拟机可能会中止,即停止   在没有干净地关闭的情况下跑步。这发生在虚拟时   机器在外部终止,例如使用SIGKILL信号   在Unix上或Microsoft Windows上的TerminateProcess调用。虚拟   例如,如果本机方法出错,机器也可能会中止   破坏内部数据结构或尝试访问   不存在的记忆。如果虚拟机中止则无法保证   可以判断是否会运行任何关闭挂钩。

您可以按如下方式使用关闭钩子:

Runtime.getRuntime().addShutdownHook(
  new Thread("app-shutdown-hook") {
    @Override 
    public void run() { 
      System.out.println("bye"); 
    }
});

您可以而且也应该在不再需要时取消注销关闭钩子。否则,JVM永远不会垃圾收集钩子。

答案 1 :(得分:2)

不确定“被杀”是什么意思?

如果是信号,则取决于信号。对于其中一些,您可以添加JVM将执行的JVM关闭挂钩...但不是全部。例如,SIGKILL即刻死亡。

使用shell代码,您可以这样做:

my java command;
# inspect $?

将其作为后台进程运行;你可以通过检查$来判断JVM是否被杀死?因为它将是128或更大(127 +用于杀死的信号数)。

请注意,如果需要,您可以同时捕获命令输出并检查$?:

output=$(my java command);
# inspect $? -- ONLY THEN inspect $output

当然,在适当的地方添加引号等等。


当然你也可以存储 $的价值?在稍后检查之前:

my command;
RC=$?;
# do something else
# inspect $RC

最后,需要注意的是,在使用System.exit()的自定义代码中,应避免使用1退出:只要main()抛出任何内容,JVM就会以返回代码退出。

答案 2 :(得分:0)

请参阅this帖子。您只需告诉运行时要在所有内容结束时执行它。多田。