首页 > 解决方案 > Windows JDK8:windows系统什么时候会重用进程对象的句柄值?

问题描述

环境

windows上的jdk8

脚步

  1. 使用 来创建一个Process实例ProcessBuilder,并使用流程的输出执行一些任务。
  2. 调用waitFor()以等待此过程完成。
  3. 使用 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 步中杀死另一个不相关的进程吗?我调试并注意到进程退出后的handleProcessImpl仍然有效。我担心当真正的进程退出但进程对象没有被jvm回收时,windows系统会重用相同的句柄。

标签: windowswinapijava-8processwin32-process

解决方案


只有在进程的最后一个句柄关闭后,进程句柄才可供重用。只要你能确保它process不会被清理,通过 PID 杀死进程就可以了。此外,由于您已经在使用 JNA,因此有更简洁的方法可以终止该进程,请参阅kernel32.TerminateProcess.

的句柄process将在 finalize 中关闭,并且Process类有一个调用destroy()也会触发一个TerminateProcess调用。大多数情况下,你不必做你正在做的事情。调用destroy之后waitFor应该可以完成这项工作。


推荐阅读