使用 Java 杀死进程

我想知道如何“终止”已经启动的进程。我知道 Process API,但我不确定,如果我能用它来“杀死”一个已经运行的进程,比如 firefox.exe 等。如果可以使用流程 API,能否请您为我指出正确的方向?如果没有,还有什么其他可行的选择?谢谢。

198035 次浏览

如果在 Java 应用程序中从 with 启动进程(例如。通过调用 Runtime.exec()ProcessBuilder.start()) ,那么您就有了对它的有效 Process引用,并且您可以调用 Process类中的 destroy()方法来终止该特定进程。

但是请注意,如果您调用的流程创建了新的子流程,那么这些子流程可能不会被终止(请参见 https://bugs.openjdk.org/browse/JDK-4770092)。

另一方面,如果您想杀死外部进程(这不是从 Java 应用程序中产生的) ,那么您可以调用允许您这样做的 O/S 实用程序。例如,您可以在 Unix/Linux 下尝试 kill命令上的 Runtime.exec(),并检查返回值,以确保应用程序是否被关闭(0表示成功,-1表示错误)。但是,这当然会使您的应用程序平台依赖于。

Process 是由 java 本身创建的进程(如 Runtime.exec (‘ firefox’))

You can use system-dependant commands like

 Runtime rt = Runtime.getRuntime();
if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1)
rt.exec("taskkill " +....);
else
rt.exec("kill -9 " +....);

在 Windows 上,可以使用此命令。

taskkill /F /IM <processname>.exe

要强行杀死它,你可以使用;

Runtime.getRuntime().exec("taskkill /F /IM <processname>.exe")

它可能是一个 java 解释器缺陷,但是 HPUX 上的 java 不执行 kill -9,而只执行 kill-TERM。

我做了一个小测试 testDestroy.java:

ProcessBuilder pb = new ProcessBuilder(args);
Process process = pb.start();
Thread.sleep(1000);
process.destroy();
process.waitFor();

还有祈祷:

$ tusc -f -p -s signal,kill -e /opt/java1.5/bin/java testDestroy sh -c 'trap "echo TERM" TERM; sleep 10'

10秒后死亡(不像预期的1秒后死亡) ,显示:

...
[19999]   Received signal 15, SIGTERM, in waitpid(), [caught], no siginfo
[19998] kill(19999, SIGTERM) ............................................................................. = 0
...

即使处理了信号,对窗口执行同样的操作似乎也会很好地终止进程(但这可能是由于窗口没有使用信号来破坏)。

事实上,我发现 用于 Linux 的 Java-Process.delete ()源代码相关的线程和 openjava 实现似乎使用-TERM,这似乎是非常错误的。

Accidentally i stumbled upon another way to do a force kill on Unix (for those who use Weblogic). This is cheaper and more elegant than running /bin/kill -9 via Exec ().

import weblogic.nodemanager.util.Platform;
import weblogic.nodemanager.util.ProcessControl;
...
ProcessControl pctl = Platform.getProcessControl();
pctl.killProcess(pid);

如果你很难得到 PID,你可以在 UNIXProcess上使用反射,例如:

Process proc = Runtime.getRuntime().exec(cmdarray, envp);
if (proc instanceof UNIXProcess) {
Field f = proc.getClass().getDeclaredField("pid");
f.setAccessible(true);
int pid = f.get(proc);
}

试试看:

String command = "killall <your_proccess>";
Process p = Runtime.getRuntime().exec(command);
p.destroy();

如果该进程仍然存在,则添加:

p.destroyForcibly();

You can kill a (SIGTERM) a windows process that was started from Java by calling the destroy method on the Process object. You can also kill any child Processes (since Java 9).

下面的代码启动一个批处理文件,等待10秒钟,然后杀死所有子进程,最后杀死批处理进程本身。

ProcessBuilder pb = new ProcessBuilder("cmd /c my_script.bat"));
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);


p.descendants().forEach(ph -> {
ph.destroy();
});


p.destroy();

使用 Java 9,我们可以使用 ProcessHandle,这使得识别和控制本地进程变得更加容易:

ProcessHandle
.allProcesses()
.filter(p -> p.info().commandLine().map(c -> c.contains("firefox")).orElse(false))
.findFirst()
.ifPresent(ProcessHandle::destroy)

其中“ firefox”是杀死的过程。

这个:

  • 首先以 Stream<ProcessHandle>的形式列出系统上运行的所有进程

  • 懒惰地过滤此流,以便只保留已启动命令行中包含“ firefox”的进程。commandLinecommand都可以使用,这取决于我们希望检索流程的方式。

  • 查找符合筛选条件的第一个筛选过程。

  • 如果至少有一个进程的命令行包含“ firefox”,那么使用 destroy杀死它。

No import necessary as ProcessHandle is part of java.lang.