Вопрос-ответ

How can a Java program get its own process ID?

Как программа Java может получить свой собственный идентификатор процесса?

Как мне получить идентификатор моего Java-процесса?

Я знаю, что существует несколько зависящих от платформы взломов, но я бы предпочел более универсальное решение.

Переведено автоматически
Ответ 1

Не существует платформенно-независимого способа, который гарантированно работал бы во всех реализациях jvm. ManagementFactory.getRuntimeMXBean().getName() выглядит как лучшее (ближайшее) решение и обычно включает PID. Он короткий и, вероятно, работает во всех широко используемых реализациях.

В Linux + Windows он возвращает значение типа "12345@hostname" (12345 являющееся идентификатором процесса). Имейте в виду, что, согласно документации, нет никаких гарантий относительно этого значения:


Возвращает имя, представляющее запущенную виртуальную машину Java. Возвращаемая строка имени может быть любой произвольной строкой, и реализация виртуальной машины Java может встроить полезную информацию для конкретной платформы в возвращаемую строку имени. Каждая запущенная виртуальная машина может иметь другое имя.


В Java 9 можно использовать новый process API:

long pid = ProcessHandle.current().pid();
Ответ 2

Вы могли бы использовать JNA. К сожалению, пока нет общего JNA API для получения текущего идентификатора процесса, но каждая платформа довольно проста:

Windows

Убедитесь, что у вас есть jna-platform.jar затем:

int pid = Kernel32.INSTANCE.GetCurrentProcessId();

Unix

Объявить:

private interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
int getpid ();
}

Тогда:

int pid = CLibrary.INSTANCE.getpid();

Java 9

В Java 9 для получения текущего идентификатора процесса можно использовать новый process API. Сначала вы получаете дескриптор текущего процесса, затем запрашиваете PID:

long pid = ProcessHandle.current().pid();
Ответ 3

Вот бэкдор-метод, который может работать не со всеми виртуальными машинами, но должен работать как в Linux, так и в Windows (оригинальный пример здесь):

java.lang.management.RuntimeMXBean runtime = 
java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =
(sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =
mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);

int pid = (Integer) pid_method.invoke(mgmt);
Ответ 4

Попробуйте Sigar . очень обширные API. Лицензия Apache 2.

private Sigar sigar;

public synchronized Sigar getSigar() {
if (sigar == null) {
sigar = new Sigar();
}
return sigar;
}

public synchronized void forceRelease() {
if (sigar != null) {
sigar.close();
sigar = null;
}
}

public long getPid() {
return getSigar().getPid();
}
java