在 Java 中终止进程的正确方法
The right way to kill a process in Java
在 Java 中终止进程的最佳方法是什么?
获取 PID 然后用 Runtime.exec()
杀死它 ?
使用destroyForcibly()
?
这两种方法有什么区别,还有其他解决方法吗?
如果您要终止的进程已被您的应用程序启动
那么您可能有对它的引用(ProcessBuilder.start()
或 Runtime.exec()
都是 return 引用)。在这种情况下,您可以简单地调用 p.destroy()
。我认为这是最干净的方法(但要小心:由 p
启动的子流程可能会继续存在,请查看 Process.destroy does not kill multiple child processes 了解更多信息)。
仅当 destroy()
在特定超时后失败时才应使用 destroyForcibly
。一言以蔽之
- 终止进程
destroy()
- 允许进程以合理的超时从容退出
- 如果进程还活着,用
destroyForcibly()
杀死它
如果你想杀死的进程是外部的
那么你没有太多选择:你需要通过OS API (Runtime.exec
)。在 Windows 上,要调用的程序将是 taskkill.exe
,而在 Mac 和 Linux 上,您可以尝试 kill
.
查看 Support for Process.destroyForcibly() and .isAlive() from Java 8 and Killing a process using Java and Code a Simple Java App to Kill Any Process After a Specified Time 了解更多信息。
如果您试图终止您的 java 代码启动的主进程,我建议您使用 System.exit()
。好处在这里解释:when should we call system exit in java.
本质上,System.exit()
将 运行 关闭挂钩,这些挂钩将确保在您的进程被杀死之前,任何可能尚未完成其工作的相关非守护进程被杀死。这是干净的方法。
如果进程不是您的,您将不得不依赖操作系统为您完成这项工作,如以下答案中所述:Killing a Process Using Java
在这种情况下,您建议 Runtime.exec()
在 *nix 上击杀是一个不错的选择。
现在至于 destroyForcibly()
,您通常会在您的 java 代码生成的子进程上调用它,该代码可能是从进程 api 的 ProcessBuilder.start()
或 Runtime.exec()
对我有用的是 System.exit(0);
它工作得很好,因为它关闭了所有仍然 运行 的进程和组件
中java8源代码
public Process destroyForcibly() {
destroy();
return this;
}
我只想说 destroyForcibly
等于 Java 中的 destroy
8.
因此,如果在调用 destroy
方法后进程仍然存在,则应尝试通过 pid 终止进程。
如果你在java 9+,你可以很容易地得到pid,只需调用Process.pid()
方法。
Java 9介绍ProcessHandle that exposes .destroy() and .destroyForcibly()方法。
TL;DR:
如果您知道进程 ID (pid),请使用 .of:
ProcessHandle.of(pid).destroy();
否则,使用 ProcessHandle.allProcesses(), inspect them with .info() 列出 运行 个进程并使用其中一种 destroy
方法。
在 Java 中终止进程的最佳方法是什么?
获取 PID 然后用 Runtime.exec()
杀死它 ?
使用destroyForcibly()
?
这两种方法有什么区别,还有其他解决方法吗?
如果您要终止的进程已被您的应用程序启动
那么您可能有对它的引用(ProcessBuilder.start()
或 Runtime.exec()
都是 return 引用)。在这种情况下,您可以简单地调用 p.destroy()
。我认为这是最干净的方法(但要小心:由 p
启动的子流程可能会继续存在,请查看 Process.destroy does not kill multiple child processes 了解更多信息)。
仅当 destroy()
在特定超时后失败时才应使用 destroyForcibly
。一言以蔽之
- 终止进程
destroy()
- 允许进程以合理的超时从容退出
- 如果进程还活着,用
destroyForcibly()
杀死它
如果你想杀死的进程是外部的
那么你没有太多选择:你需要通过OS API (Runtime.exec
)。在 Windows 上,要调用的程序将是 taskkill.exe
,而在 Mac 和 Linux 上,您可以尝试 kill
.
查看 Support for Process.destroyForcibly() and .isAlive() from Java 8 and Killing a process using Java and Code a Simple Java App to Kill Any Process After a Specified Time 了解更多信息。
如果您试图终止您的 java 代码启动的主进程,我建议您使用 System.exit()
。好处在这里解释:when should we call system exit in java.
本质上,System.exit()
将 运行 关闭挂钩,这些挂钩将确保在您的进程被杀死之前,任何可能尚未完成其工作的相关非守护进程被杀死。这是干净的方法。
如果进程不是您的,您将不得不依赖操作系统为您完成这项工作,如以下答案中所述:Killing a Process Using Java
在这种情况下,您建议 Runtime.exec()
在 *nix 上击杀是一个不错的选择。
现在至于 destroyForcibly()
,您通常会在您的 java 代码生成的子进程上调用它,该代码可能是从进程 api 的 ProcessBuilder.start()
或 Runtime.exec()
对我有用的是 System.exit(0); 它工作得很好,因为它关闭了所有仍然 运行 的进程和组件
中java8源代码
public Process destroyForcibly() {
destroy();
return this;
}
我只想说 destroyForcibly
等于 Java 中的 destroy
8.
因此,如果在调用 destroy
方法后进程仍然存在,则应尝试通过 pid 终止进程。
如果你在java 9+,你可以很容易地得到pid,只需调用Process.pid()
方法。
Java 9介绍ProcessHandle that exposes .destroy() and .destroyForcibly()方法。
TL;DR:
如果您知道进程 ID (pid),请使用 .of:
ProcessHandle.of(pid).destroy();
否则,使用 ProcessHandle.allProcesses(), inspect them with .info() 列出 运行 个进程并使用其中一种 destroy
方法。