Java程序如何获得自己的进程ID?
如何获取我的 Java 进程的 ID?
我知道有几种依赖于平台的技巧,但我更喜欢更通用的解决方案。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如何获取我的 Java 进程的 ID?
我知道有几种依赖于平台的技巧,但我更喜欢更通用的解决方案。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(23)
基于 Ashwin Jayaprakash 的答案 (+1)
关于 Apache 2.0 许可的
SIGAR
,以下是我如何使用它来仅获取当前进程的 PID:尽管它不能在所有平台上工作,但它可以在 Linux、Windows、OS X 和各种 Unix 平台如此处所列。
Based on Ashwin Jayaprakash's answer (+1)
about the Apache 2.0 licensed
SIGAR
, here is how I use it to get only the PID of the current process:Even though it does not work on all platforms, it does work on Linux, Windows, OS X and various Unix platforms as listed here.
这是我的解决方案:
Here is my solution:
对于JDK< Linux 上的 9:
您不需要解析文本格式的
/proc/self/stat
,只需使用 syscall:readlink 和 procfs 实现。For JDK < 9 on Linux:
You don't need to parse the text-formatted
/proc/self/stat
, just use the syscall:readlink and the procfs implementation.我发现了一个可能有点边缘情况的解决方案,并且我没有在 Windows 10 之外的其他操作系统上尝试过它,但我认为它值得注意。
如果您发现自己正在使用 J2V8 和 nodejs,您可以运行一个简单的 javascript 函数,返回 pid java进程。
这是一个例子:
I found a solution that may be a bit of an edge case and I didn't try it on other OS than Windows 10, but I think it's worth noticing.
If you find yourself working with J2V8 and nodejs, you can run a simple javascript function returning you the pid of the java process.
Here is an example:
您可以在 JNR-Posix 中尝试
getpid()
。它有一个 Windows POSIX 包装器,可以调用 libc 的 getpid() 。
You can try
getpid()
in JNR-Posix.It has a Windows POSIX wrapper that calls getpid() off of libc.
我知道这是一个旧线程,但我想指出用于获取 PID(以及运行时 Java 进程的其他操作)的 API 已添加到 JDK 9 中的 Process 类中: http://openjdk.java.net/jeps/102
I know this is an old thread, but I wanted to call out that API for getting the PID (as well as other manipulation of the Java process at runtime) is being added to the Process class in JDK 9: http://openjdk.java.net/jeps/102
这是 JConsole、jps 和 VisualVM 可能使用的代码。 它利用来自的类
sun.jvmstat.monitor.*
包,来自tool.jar
。有几个问题:
tool.jar
是一个随 Oracle JDK 而不是 JRE 分发的库!tool.jar
; 使用 Maven 配置它有点棘手tool.jar
可能包含平台相关的(本机?)代码,所以它并不容易可分发
从 Java 6 开始,所有应用程序通常都是(除非您主动配置相反)
MonitoredVmUtil 中的错误?
更新:我刚刚仔细检查过 JPS 使用这种方式,即 Jvmstat 库(tool.jar 的一部分)。 所以不需要调用JPS作为外部进程,直接调用Jvmstat库,如我的示例所示。 您还可以通过这种方式获取在本地主机上运行的所有 JVM 的列表。
请参阅 JPS 源代码:
This is the code JConsole, and potentially jps and VisualVM uses. It utilizes classes from
sun.jvmstat.monitor.*
package, fromtool.jar
.There are few catches:
tool.jar
is a library distributed with Oracle JDK but not JRE!tool.jar
from Maven repo; configure it with Maven is a bit trickytool.jar
probably contains platform dependent (native?) code so it is not easilydistributable
that from Java 6 all apps generally are (unless you actively configure opposite)
Bug in MonitoredVmUtil?
UPDATE: I have just double checked that JPS uses this way, that is Jvmstat library (part of tool.jar). So there is no need to call JPS as external process, call Jvmstat library directly as my example shows. You can aslo get list of all JVMs runnin on localhost this way.
See JPS source code:
这是我有类似需求时使用的。 这正确地确定了Java进程的PID。 让您的 java 代码在预定义的端口号上生成一个服务器,然后执行操作系统命令以找出侦听该端口的 PID。 对于Linux
This is what I used when I had similar requirement. This determines the PID of the Java process correctly. Let your java code spawn a server on a pre-defined port number and then execute OS commands to find out the PID listening on the port. For Linux
您可以使用 JNA。 不幸的是,还没有通用的 JNA API 来获取当前进程 ID,但每个平台都非常简单:
Windows
确保您有
jna-platform.jar
然后:Unix
声明:
然后:
Java 9
在 Java 下9 新的 process API 可用于获取当前进程ID。 首先获取当前进程的句柄,然后查询 PID:
You could use JNA. Unfortunately there is no common JNA API to get the current process ID yet, but each platform is pretty simple:
Windows
Make sure you have
jna-platform.jar
then:Unix
Declare:
Then:
Java 9
Under Java 9 the new process API can be used to get the current process ID. First you grab a handle to the current process, then query the PID:
在 Scala 中:
这应该为您提供 Unix 系统上的解决方法,直到 Java 9 发布。
(我知道,这个问题是关于 Java 的,但由于 Scala 没有类似的问题,所以我想把这个问题留给可能遇到同样问题的 Scala 用户。)
In Scala:
This should give you a workaround on Unix systems until Java 9 will be released.
(I know, the question was about Java, but since there is no equivalent question for Scala, I wanted to leave this for Scala users who might stumble into the same question.)
这是一个后门方法,可能不适用于所有虚拟机,但应该适用于 Linux 和 Windows (原始示例在这里):
Here's a backdoor method which might not work with all VMs but should work on both linux and windows (original example here):
不存在可以保证在所有 jvm 实现中工作的独立于平台的方法。
ManagementFactory.getRuntimeMXBean().getName()
看起来是最好(最接近)的解决方案,通常包含 PID。 它很短,可能适用于广泛使用的每个实现。在 linux+windows 上,它返回一个类似
"12345@hostname"
的值(12345
是进程 ID)。 但请注意 根据文档,对此值没有任何保证:在 Java 9 中,新的进程可以使用API:
There exists no platform-independent way that can be guaranteed to work in all jvm implementations.
ManagementFactory.getRuntimeMXBean().getName()
looks like the best (closest) solution, and typically includes the PID. It's short, and probably works in every implementation in wide use.On linux+windows it returns a value like
"12345@hostname"
(12345
being the process id). Beware though that according to the docs, there are no guarantees about this value:In Java 9 the new process API can be used:
使用 Java 10,获取
进程 ID
With Java 10, to get
process id
这取决于您从哪里寻找信息。
如果您要从控制台查找信息,可以使用 jps 命令。 该命令提供类似于 Unix ps 命令的输出,并且自 1.5 起就随 JDK 一起提供。
如果您从进程中查看,RuntimeMXBean(如 Wouter Coekaerts 所说)可能是您的最佳选择。 使用 Sun JDK 1.6 u7 的 Windows 上的 getName() 的输出格式为 [PROCESS_ID]@[MACHINE_NAME]。 但是,您可以尝试执行 jps 并解析结果:
如果不带任何选项运行,则输出应该是进程 ID 后跟名称。
It depends on where you are looking for the information from.
If you are looking for the information from the console you can use the jps command. The command gives output similar to the Unix ps command and comes with the JDK since I believe 1.5
If you are looking from the process the RuntimeMXBean (as said by Wouter Coekaerts) is probably your best choice. The output from getName() on Windows using Sun JDK 1.6 u7 is in the form [PROCESS_ID]@[MACHINE_NAME]. You could however try to execute jps and parse the result from that:
If run with no options the output should be the process id followed by the name.
我最新发现的是,有一个名为
sun.java.launcher.pid
的系统属性,至少在 Linux 上可用。 我的计划是使用它,如果找不到,则使用JMX bean
。The latest I have found is that there is a system property called
sun.java.launcher.pid
that is available at least on linux. My plan is to use that and if it is not found to use theJMX bean
.为了完整起见,Spring Boot 中有一个
解决方案的包装器。 如果需要一个整数,那么这可以总结为一句话:
如果有人已经使用 Spring boot,她/他可能会使用 org.springframework.boot.ApplicationPid
toString() 方法打印pid 或“???”。
使用 ManagementFactory 的注意事项已在其他答案中讨论过。
For completeness there is a wrapper in Spring Boot for the
solution. If an integer is required, then this can be summed up to the one-liner:
If someone uses Spring boot already, she/he might use org.springframework.boot.ApplicationPid
The toString() method prints the pid or '???'.
Caveats using the ManagementFactory are discussed in other answers already.
对于较旧的 JVM,在 Linux 中...
For older JVM, in linux...
您可以在 GitHub 上查看我的项目:JavaSysMon。 它提供进程 ID 和一堆其他跨平台信息(CPU 使用情况、内存使用情况)(目前为 Windows、Mac OSX、Linux 和 Solaris)
You can check out my project: JavaSysMon on GitHub. It provides process id and a bunch of other stuff (CPU usage, memory usage) cross-platform (presently Windows, Mac OSX, Linux and Solaris)
从 Java 9 开始,有一个方法 < code>Process.pid() 返回进程的本机 ID:
要获取当前 Java 进程的进程 ID,可以使用
ProcessHandle
接口:Since Java 9 there is a method
Process.pid()
which returns the native ID of a process:To get the process ID of the current Java process one can use the
ProcessHandle
interface:尝试 Sigar 。 非常广泛的 API。 阿帕奇 2 许可证。
Try Sigar . very extensive APIs. Apache 2 license.
以下方法尝试从
java.lang.management.ManagementFactory
中提取 PID:例如,只需调用
getProcessId("")
即可。The following method tries to extract the PID from
java.lang.management.ManagementFactory
:Just call
getProcessId("<PID>")
, for instance.