我目前正在维护一个在故障发生时使用system.exit(1)关闭的系统。不幸的是,当这种情况发生时,java进程仍然存在。
为什么jvm在调用system.exit后没有关闭呢?
我目前正在维护一个在故障发生时使用system.exit(1)关闭的系统。不幸的是,当这种情况发生时,java进程仍然存在。
为什么jvm在调用system.exit后没有关闭呢?
那是因为System.exit(1)
不会停止应用程序关闭钩子,应该使用System.exit(0);
。
事实上,System.exit(1)
会“暂停并停止”,根据这段代码:
/* Invoked by Runtime.exit, which does all the security checks.
* Also invoked by handlers for system-provided termination events,
* which should pass a nonzero status code.
*/
static void exit(int status) {
boolean runMoreFinalizers = false;
synchronized (lock) {
if (status != 0) runFinalizersOnExit = false;
switch (state) {
case RUNNING: /* Initiate shutdown */
state = HOOKS;
break;
case HOOKS: /* Stall and halt */
break;
case FINALIZERS:
if (status != 0) {
/* Halt immediately on nonzero status */
halt(status);
} else {
/* Compatibility with old behavior:
* Run more finalizers and then halt
*/
runMoreFinalizers = runFinalizersOnExit;
}
break;
}
}
if (runMoreFinalizers) {
runAllFinalizers();
halt(status);
}
synchronized (Shutdown.class) {
/* Synchronize on the class object, causing any other thread
* that attempts to initiate shutdown to stall indefinitely
*/
sequence();
halt(status);
}
}
一个可能性是调用System.exit(...)
时抛出了SecurityException
异常。
请参考https://dev59.com/IHA65IYBdhLWcg3wogIb#19823373,可能会有一个解决方案。基本思路是在单独的线程中触发System.exit而不是在主线程中触发。