Windows JDK8: Когда система Windows повторно использует значение дескриптора объекта процесса? - PullRequest
0 голосов
/ 22 апреля 2019

Окружающая среда

JDK8 на Windows

Steps

  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? Я отладил и заметил, что handle значение ProcessImpl остается действительным даже после завершения процесса. Я обеспокоен тем, что система Windows будет использовать тот же дескриптор, когда реальный процесс будет завершен, но объект процесса не будет переработан jvm.

1 Ответ

0 голосов
/ 22 апреля 2019

Дескриптор процесса становится доступным для повторного использования только после закрытия последнего дескриптора процесса .Пока вы можете быть уверены, что process не очищен, уничтожение процесса с помощью PID - это нормально.Кроме того, есть более чистые способы уничтожения процесса, поскольку вы уже используете JNA, см. kernel32.TerminateProcess.

Дескриптор для process будет закрыт в финализации, также класс Process имеет вызов на destroy(), который также вызовет вызов TerminateProcess.В основном вам не нужно делать то, что вы делаете здесь.Вызов destroy, за которым следует waitFor, должен сделать эту работу.

...