当前位置:  开发笔记 > 编程语言 > 正文

Java程序如何获得自己的进程ID?

如何解决《Java程序如何获得自己的进程ID?》经验,为你挑选了13个好方法。

如何获取Java进程的ID?

我知道有几个依赖于平台的黑客,但我更喜欢更通用的解决方案.



1> Wouter Coeka..:

没有平台无关的方式可以保证在所有jvm实现中都能工作. ManagementFactory.getRuntimeMXBean().getName()看起来像最好(最接近)的解决方案.它很简短,可能适用于广泛使用的每个实现.

在linux + windows上,它返回一个像12345@hostname(12345作为进程id)的值.请注意,根据文档,不保证这个值:

返回表示正在运行的Java虚拟机的名称.返回的名称字符串可以是任意字符串,Java虚拟机实现可以选择在返回的名称字符串中嵌入特定于平台的有用信息.每个正在运行的虚拟机可以具有不同的名称.

在Java 9中,可以使用新的流程API:

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


这个解决方案非常脆弱.请在下面看到关于Hyperic Sigar的答案.

2> Luke Quinane..:

你可以使用JNA.遗憾的是,目前没有通用的JNA API来获取当前的进程ID,但每个平台都非常简单:

视窗

确保你有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下,新的流程API可用于获取当前进程ID.首先,您获取当前进程的句柄,然后查询PID:

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


+1但我担心在安全受限的环境中它不应该工作(tomcat,WebLogic等).

3> Brad Mace..:

这是一个后门方法,它可能不适用于所有虚拟机,但应该适用于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);


适用于1.7 ..不适用于1.8:|
非常好,只是验证它在JRockit和Hotspot JVM上都有效.
Oracle Java团队宣布他们打算隐藏所有非java软件包(即sun.*).我相信从Java 10开始(计划于2018年 - 也许是Java 9).如果您具有与上面类似的实现,您可能想要找出一个替代方案,以便您的代码不会中断.

4> Ashwin Jayap..:

试试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();
    }


如果您解释*如何*为此使用SIGAR,您会有更多的赞成

5> Martin..:

以下方法尝试从以下位置提取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 '@', 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("")例如,请致电.


VisualVM使用类似的代码来获取自身PID,请检查com.sun.tools.visualvm.application.jvm.Jvm#ApplicationSupport #createCurrentApplication().他们是专家,因此它看起来像可靠的跨平台解决方案.

6> 小智..:

对于较旧的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";
}


如果你要这样做,那就做`int pid = Integer.parseInt(new File("/ proc/self").getCanonicalFile().getName());`.为什么额外的旋转?
getCanonicalFile()解析符号链接/ proc/self/ - >/proc/1234,试试ls -al/proc/self
对于好奇,@ David的评论中的诀窍实际上是有效的.有人可以说为什么?`getCanonicalFile()`方法中的某种魔法将"self"转换为PID?
@DavidCitron +1!你是对的,我没想到getCanonicalFile :-)

7> 小智..:

你可以看看我的项目:GitHub上的JavaSysMon.它提供了进程ID和一堆其他东西(CPU使用,内存使用)跨平台(目前是Windows,Mac OSX,Linux和Solaris)



8> ZhekaKozlov..:

从Java 9开始,有一个方法Process.getPid(),它返回进程的本机ID:

public abstract class Process {

    ...

    public long getPid();
}

要获取当前Java进程的进程ID,可以使用该ProcessHandle接口:

System.out.println(ProcessHandle.current().pid());


您能解释一下如何在Java 9中获取当前运行进程的Process实例吗?

9> 小智..:

在斯卡拉:

import sys.process._
val pid: Long = Seq("sh", "-c", "echo $PPID").!!.trim.toLong

这将为您提供Unix系统的解决方法,直到Java 9发布.(我知道,这个问题是关于Java的,但是由于Scala没有相同的问题,我想把它留给可能会遇到同样问题的Scala用户.)



10> l00tr..:

为了完整存在的包装春天启动

String jvmName = ManagementFactory.getRuntimeMXBean().getName();
return jvmName.split("@")[0];

解.如果需要一个整数,那么这可以总结为一行:

int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);

如果有人使用Spring启动,她/他可能会使用org.springframework.boot.ApplicationPid

ApplicationPid pid = new ApplicationPid();
pid.toString();

toString()方法打印pid或'???'.

使用ManagementFactory的注意事项已在其他答案中讨论.



11> Jaskey..:
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;
}



12> markus..:
java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split("@")[0]



13> 小智..:

我发现最新的是,有一个系统属性名为sun.java.launcher.pid可用至少在Linux上.我的计划是使用它,如果没有找到使用它JMX bean.

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有