使用Java杀死进程

时间:2011-06-15 10:29:39

标签: java process

我想知道如何“杀死”已启动的进程。我知道Process API,但我不确定,如果我可以使用它来“杀死”已经运行的进程,例如firefox.exe等。如果可以使用Process API,请指点我进入正确的方向?如果没有,其他可用选项有哪些?感谢。

8 个答案:

答案 0 :(得分:56)

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

taskkill /F /IM <processname>.exe 

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

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

答案 1 :(得分:51)

如果您在Java应用程序中启动了该过程(例如,通过调用Runtime.exec()ProcessBuilder.start()),那么您有一个有效的Process引用,并且您可以调用destroy()类中的Process方法可以杀死该特定进程。

但请注意,如果您调用的进程创建新的子进程,则可能不会终止这些进程(请参阅http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092)。

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

答案 2 :(得分:30)

AFAIU java.lang.Process是java本身创建的进程(如Runtime.exec('firefox'))

您可以使用与系统相关的命令,例如

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

答案 3 :(得分:4)

无意中我偶然发现了另一种在Unix上强行杀死的方式(对于那些使用Weblogic的人)。这比通过 Runtime.exec()运行/ bin / kill -9更便宜,更优雅。

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

如果你很难获得pid,你可以在 java.lang.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);
}

答案 4 :(得分:3)

它可能是一个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
...

即使处理了信号,在Windows上执行相同操作似乎也会使进程失效(但可能是因为Windows没有使用信号来销毁)。

实际上我发现Java - Process.destroy() source code for Linux相关的线程和openjava实现似乎也使用-TERM,这似乎非常错误。

答案 5 :(得分:2)

试一试:

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

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

p.destroyForcibly();

答案 6 :(得分:1)

使用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将其杀死。

ProcessHandlejava.lang的一部分,因此无需导入。

答案 7 :(得分:0)

您可以通过调用Process对象上的destroy方法来杀死(SIGTERM)从Java启动的Windows进程。您也可以杀死任何子进程(自Java 9开始)。

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

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import * as CanvasJS from 'canvasjs';

@Component({
  selector: 'app-canvas-js',
  templateUrl: './canvas-js.component.html',
  styleUrls: ['./canvas-js.component.scss']
})
export class CanvasJsComponent implements OnInit {
canvasChartData: any;
  canvasChartDataCopy: number[];
  canvasChart: any;
  canvasChartContext: any;

  constructor() { }

  ngOnInit() {
  let dataPoints = [];
	let y = 0;		
	for ( var i = 0; i < 10000; i++ ) {		  
		y += Math.round(5 + Math.random() * (-5 - 5));	
		dataPoints.push({ y: y});
	}
	let chart = new CanvasJS.Chart("canvasjsContainer", {
		zoomEnabled: true,
	  animationEnabled: true,
		exportEnabled: true,
		title: {
			text: "Performance Demo - 10000 DataPoints"
		},
		subtitles:[{
			text: "Try Zooming and Panning"
		}],
		data: [
		{
			type: "line",                
			dataPoints: dataPoints
		}]
	});
		
	chart.render();
}
}