windows - Windows JDK8:windows系统什么时候会重用进程对象的句柄值?
问题描述
环境
windows上的jdk8
脚步
- 使用 来创建一个
Process
实例ProcessBuilder
,并使用流程的输出执行一些任务。 - 调用
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 步中杀死另一个不相关的进程吗?我调试并注意到进程退出后的handle
值ProcessImpl
仍然有效。我担心当真正的进程退出但进程对象没有被jvm回收时,windows系统会重用相同的句柄。
解决方案
只有在进程的最后一个句柄关闭后,进程句柄才可供重用。只要你能确保它process
不会被清理,通过 PID 杀死进程就可以了。此外,由于您已经在使用 JNA,因此有更简洁的方法可以终止该进程,请参阅kernel32.TerminateProcess
.
的句柄process
将在 finalize 中关闭,并且Process
类有一个调用destroy()
也会触发一个TerminateProcess
调用。大多数情况下,你不必做你正在做的事情。调用destroy
之后waitFor
应该可以完成这项工作。
推荐阅读
- c# - 如何将 Azure 函数的连接字符串加密到 ServiceBus
- java - 可以同时指向 WireMock 和真实实例的集成测试,具体取决于它运行的位置
- android - 从另一个应用程序启动不是主要活动
- angular - Angular 事件发射问题
- linux - 切换到树莓派交叉编译器会破坏 ncurses
- kubernetes - 字段 kubernetes.io/ingress.class 的 Helm 升级命令错误
- java - 在 tomcat-embed-jasper 中禁用 JSP 池
- c++ - “自动”推断 hashtable_policy.h 中的类型不正确
- sql - SQL 在第二个表上连接所有不同的行,显示两个表中的一列
- react-native - 使用 Visual Studio App Center 进行身份验证时,必须从 Expo 中退出吗?