如何获得我的Java进程的id ?

我知道有一些平台相关的黑客,但我更喜欢一个更通用的解决方案。


当前回答

我知道这是一个旧线程,但我想要调用用于获取PID的API(以及在运行时对Java进程的其他操作)正在添加到JDK 9中的process类:http://openjdk.java.net/jeps/102

其他回答

这取决于你从哪里寻找信息。

如果要从控制台查找信息,可以使用jps命令。该命令的输出类似于Unix ps命令,并随JDK一起提供,因为我相信是1.5版本

如果从流程的角度来看,RuntimeMXBean(正如Wouter Coekaerts所说)可能是您的最佳选择。在使用Sun JDK 1.6 u7的Windows上,getName()的输出格式为[PROCESS_ID]@[MACHINE_NAME]。然而,你可以尝试执行jps并解析结果:

String jps = [JDK HOME] + "\\bin\\jps.exe";
Process p = Runtime.getRuntime().exec(jps);

如果运行时没有选项,输出应该是进程id后跟进程名。

下面的方法尝试从java.lang.management.ManagementFactory中提取PID:

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>")。

java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split("@")[0]

下面是一个后门方法,它可能不适用于所有的虚拟机,但应该适用于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);
public static long getPID() {
    String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
    if (processName != null && processName.length() > 0) {
        try {
            return Long.parseLong(processName.split("@")[0]);
        }
        catch (Exception e) {
            return 0;
        }
    }

    return 0;
}