Windows JDK8:windows系统什么时候会重用进程对象的句柄值?
Windows JDK8: When will the windows system reuse the handle value of a process object?
环境
jdk8 在 windows
步骤
- 使用
ProcessBuilder
创建一个 Process
实例,并使用进程的输出执行一些任务。
- 调用
waitFor()
等待此过程完成。
- 使用jna+cmd强行杀掉进程。我在
finally
块中执行此操作以确保进程始终终止。
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handleValue = f.getLong(process);
WinNT.HANDLE handle = new WinNT.HANDLE();
handle.setPointer(Pointer.createConstant(handleValue));
Kernel32 kernel = Kernel32.INSTANCE;
int pid = kernel.GetProcessId(handle);
Process killPr = Runtime.getRuntime().exec("cmd /c taskkill /pid " + pid + " /f /t");
killPr.waitFor();
killPr.destroy();
问题
执行上述步骤安全吗?我会在第 3 步中杀死另一个不相关的进程吗?我调试发现,ProcessImpl
的handle
值在进程退出后仍然有效。我担心 windows 当 真正的进程 退出但 进程对象 没有被回收时,系统会重用同一个句柄jvm.
Process handle becomes available for reuse only after the last handle to the process is closed。只要能保证process
不被清理掉,用PID杀进程就可以了。此外,由于您已经在使用 JNA,因此还有更简洁的方法来终止进程,请参阅 kernel32.TerminateProcess
。
process
的句柄将在 finalize 中关闭,Process
class 也会调用 destroy()
,这也会触发 TerminateProcess
称呼。大多数情况下,你不必做你在这里做的事情。调用 destroy
然后调用 waitFor
应该可以完成工作。
环境
jdk8 在 windows
步骤
- 使用
ProcessBuilder
创建一个Process
实例,并使用进程的输出执行一些任务。 - 调用
waitFor()
等待此过程完成。 - 使用jna+cmd强行杀掉进程。我在
finally
块中执行此操作以确保进程始终终止。
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handleValue = f.getLong(process);
WinNT.HANDLE handle = new WinNT.HANDLE();
handle.setPointer(Pointer.createConstant(handleValue));
Kernel32 kernel = Kernel32.INSTANCE;
int pid = kernel.GetProcessId(handle);
Process killPr = Runtime.getRuntime().exec("cmd /c taskkill /pid " + pid + " /f /t");
killPr.waitFor();
killPr.destroy();
问题
执行上述步骤安全吗?我会在第 3 步中杀死另一个不相关的进程吗?我调试发现,ProcessImpl
的handle
值在进程退出后仍然有效。我担心 windows 当 真正的进程 退出但 进程对象 没有被回收时,系统会重用同一个句柄jvm.
Process handle becomes available for reuse only after the last handle to the process is closed。只要能保证process
不被清理掉,用PID杀进程就可以了。此外,由于您已经在使用 JNA,因此还有更简洁的方法来终止进程,请参阅 kernel32.TerminateProcess
。
process
的句柄将在 finalize 中关闭,Process
class 也会调用 destroy()
,这也会触发 TerminateProcess
称呼。大多数情况下,你不必做你在这里做的事情。调用 destroy
然后调用 waitFor
应该可以完成工作。