简体   繁体   English

Java中杀死进程的正确方法

[英]The right way to kill a process in Java

What's the best way to kill a process in Java?在 Java 中终止进程的最佳方法是什么?

Get the PID and then killing it with Runtime.exec() ?获取 PID 然后用Runtime.exec()杀死它?

Use destroyForcibly() ?使用destroyForcibly()

What's the difference between these two methods, and is there any others solutions?这两种方法有什么区别,还有其他解决方案吗?

If the process you want to kill has been started by your application 如果您要杀死的进程已由您的应用程序启动

Then you probably have a reference to it ( ProcessBuilder.start() or Runtime.exec() both return a reference). 然后你可能有一个引用它( ProcessBuilder.start()Runtime.exec()都返回一个引用)。 In this case, you can simply call p.destroy() . 在这种情况下,您只需调用p.destroy() I think this is the cleanest way (but be careful: sub-processes started by p may stay alive, check http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092 for more info). 我认为这是最干净的方式(但要小心: p启动的子流程可能会保持活跃状态​​,请查看http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092获取更多信息)。

The destroyForcibly should only be used if destroy() failed after a certain timeout. 只有在某个超时后destroy()失败时才应使用destroyForcibly In a nutshell 简而言之

  1. terminate process with destroy() destroy()终止进程
  2. allow process to exit gracefully with reasonable timeout 允许进程在合理的超时时间内正常退出
  3. kill it with destroyForcibly() if process is still alive 如果进程仍然存在,则使用destroyForcibly()其杀死

If the process you want to kill is external 如果要杀死的进程是外部的

Then you don't have much choice: you need to pass through the OS API ( Runtime.exec ). 那么你没有太多选择:你需要通过OS API( Runtime.exec )。 On Windows, the program to call will be taskkill.exe , while on Mac and Linux you can try kill . 在Windows上,要调用的程序将是taskkill.exe ,而在Mac和Linux上,您可以尝试kill


Have a look at https://github.com/zeroturnaround/zt-exec/issues/19 and Killing a process using Java and http://invisiblecomputer.wonderhowto.com/how-to/code-simple-java-app-kill-any-process-after-specified-time-0133513/ for more info. 看看https://github.com/zeroturnaround/zt-exec/issues/19使用Javahttp://invisiblecomputer.wonderhowto.com/how-to/code-simple-java-app- 杀死一个进程 kill-any-process-after-specified-time-0133513 /获取更多信息。

If you're trying to kill the main process your java code started, I'd suggest using System.exit() . 如果你试图杀死java代码启动的主进程,我建议使用System.exit() The benefits are explained here: when should we call system exit in java . 这里解释了这些好处: 我们何时应该在java中调用system exit

Essentially, System.exit() will run shutdown hooks that will make sure any dependent non-daemon processes that may not have completed their work are killed before your process is killed. 从本质上讲, System.exit()将运行关闭挂钩,以确保在您的进程被终止之前,任何可能尚未完成其工作的从属非守护进程被杀死。 This is the clean way to do it. 这是干净的方法。

If the process is not yours, you will have to rely on the Operating System to do this work for you as explained in this answer: Killing a Process Using Java 如果该过程不属于您,则必须依赖操作系统为您完成此工作,如本答案中所述: 使用Java杀死进程

In that case your suggestion of Runtime.exec() a kill on *nix would be a decent way to go. 在这种情况下,你建议Runtime.exec()杀死* nix将是一个不错的方式。

Now as for destroyForcibly() , you're typically going to call that on a child process spawned by your java code that was presumably started with the process api's ProcessBuilder.start() or Runtime.exec() 现在和destroyForcibly() ,你通常会在你的java代码生成的子进程上调用它,这个代码可能是从进程api的ProcessBuilder.start()Runtime.exec()

Java 9 introduced ProcessHandle that exposes .destroy() and .destroyForcibly() methods. Java 9 引入了公开.destroy().destroyForcibly()方法的ProcessHandle

TL;DR :长话短说

If you know the process ID (pid) then use " .of ":如果您知道进程 ID (pid),则使用“ .of ”:

ProcessHandle.of(pid).destroy();

Otherwise take the following steps:否则采取以下步骤:

  1. list all currently running processes with ProcessHandle.allProcesses()使用ProcessHandle.allProcesses()列出所有当前正在运行的进程
  2. inspect them with .info().info()检查它们
  3. use one of destroy methods mentioned above.使用上面提到的destroy方法之一。

the one that worked for me is System.exit(0); 对我有用的是System.exit(0); it's work's well because it closes all still running processes and components 它的工作很好,因为它关闭了所有仍在运行的进程和组件

In java 8 source code 在java 8源代码中

public Process destroyForcibly() {
    destroy();
    return this;
}

I just want to say that the destroyForcibly is equal to the destroy in Java 8. 我只想说destroyForcibly等于Java 8中的destroy
So you should try to kill the process by pid if process is still alive after you called the destroy method. 因此,如果在调用destroy方法后进程仍处于活动状态,则应尝试使用pid终止进程。 You can easily get the pid if you are on java 9+,just call Process.pid() method. 如果你使用的是java 9 +,只需调用Process.pid()方法即可轻松获取pid。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM