[java] Java 프로그램은 어떻게 자체 프로세스 ID를 얻을 수 있습니까?

Java 프로세스의 ID를 어떻게 얻습니까?

나는 플랫폼에 의존하는 여러 해킹이 있다는 것을 알고 있지만 더 일반적인 솔루션을 선호합니다.



답변

모든 jvm 구현에서 작동하도록 보장 할 수있는 플랫폼 독립적 인 방법은 없습니다.
ManagementFactory.getRuntimeMXBean().getName()최고의 (가장 가까운) 솔루션처럼 보입니다. 짧고 아마도 모든 구현에서 널리 사용됩니다.

linux + windows에서는 12345@hostname( 12345프로세스 ID) 와 같은 값을 반환합니다 . 있다고하더라도 조심 워드 프로세서에 따르면 ,이 값에 대한 보장이 없습니다 :

실행중인 Java 가상 머신을 나타내는 이름을 리턴합니다. 리턴 된 이름 문자열은 임의의 문자열 일 수 있으며 Java 가상 머신 구현은 플랫폼 별 유용한 정보를 리턴 된 이름 문자열에 임베드하도록 선택할 수 있습니다. 실행중인 각 가상 머신의 이름이 다를 수 있습니다.

Java 9 에서는 새로운 프로세스 API를 사용할 수 있습니다.

long pid = ProcessHandle.current().pid();


답변

JNA를 사용할 수 있습니다 . 불행히도 현재 프로세스 ID를 얻는 일반적인 JNA API는 없지만 각 플랫폼은 매우 간단합니다.

윈도우

jna-platform.jar다음이 있는지 확인하십시오 .

int pid = Kernel32.INSTANCE.GetCurrentProcessId();

유닉스

알리다:

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

그때:

int pid = CLibrary.INSTANCE.getpid();

자바 9

Java 9에서는 새 프로세스 API 를 사용하여 현재 프로세스 ID를 얻을 수 있습니다. 먼저 현재 프로세스에 대한 핸들을 잡고 PID를 쿼리하십시오.

long pid = ProcessHandle.current().pid();


답변

다음 은 모든 VM에서 작동하지 않을 있지만 Linux 및 Windows 모두에서 작동해야하는 백도어 방법입니다 ( 원본 예제 here ).

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);


답변

시가를 보십시오 . 매우 광범위한 API. 아파치 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();
}


답변

다음 방법은 PID를 추출하려고 시도합니다 java.lang.management.ManagementFactory.

private static String getProcessId(final String fallback) {
    // Note: may fail in some JVM implementations
    // therefore fallback has to be provided

    // something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
    final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
    final int index = jvmName.indexOf('@');

    if (index < 1) {
        // part before '@' empty (index = 0) / '@' not found (index = -1)
        return fallback;
    }

    try {
        return Long.toString(Long.parseLong(jvmName.substring(0, index)));
    } catch (NumberFormatException e) {
        // ignore
    }
    return fallback;
}

getProcessId("<PID>")예를 들어 전화하십시오 .


답변

이전 JVM의 경우 Linux에서 …

private static String getPid() throws IOException {
    byte[] bo = new byte[256];
    InputStream is = new FileInputStream("/proc/self/stat");
    is.read(bo);
    for (int i = 0; i < bo.length; i++) {
        if ((bo[i] < '0') || (bo[i] > '9')) {
            return new String(bo, 0, i);
        }
    }
    return "-1";
}


답변

내 프로젝트를 확인할 수 있습니다 : GitHub의 JavaSysMon . 프로세스 ID와 다른 플랫폼 (CPU 사용량, 메모리 사용량) 크로스 플랫폼 (현재 Windows, Mac OSX, Linux 및 Solaris)을 제공합니다.