我们希望在JVM手动终止时退出之前执行一些java代码或shell代码。我们的应用程序没有在容器中运行。我们需要使用Java代码本身或某些命令行工具自动监视它。
答案 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帖子。您只需告诉运行时要在所有内容结束时执行它。多田。