本文最后更新于 178 天前 ,文中信息可能已经过时。如有问题请在评论区留言。

ManagementFactory

ManagementFactory 是一个为我们提供各种获取 JVM 信息的工厂类,使用 ManagementFactory 可以获取大量的运行时 JVM 信息,比如 JVM 堆的使用情况,GC 情况,线程信息等。通过这些数据项我们可以了解正在运行的 JVM 的情况,以便我们可以做出相应的调整。

使用 ManagementFactory 获取运行时进程 PID 方式如下:

java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.lang.management.ManagementFactory;

public class JVMUtil {

    /**
     * 方式一: 根据 SystemProperties 获取 PID
     * 
     * @since JDK 1.5
     */
    public static long getPID() {
        return Long.parseLong(ManagementFactory.getRuntimeMXBean().getSystemProperties().get("PID"));
    }

    /**
     * 方式二: 根据 Name 截取 PID 
     *
     * @since JDK 1.5
     */
    public static long getPID() {
        return Long.parseLong(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
    }
  
    /**
     * 方式三: 直接获取 PID
     *
     * @since JDK 10
     */
    public static long getPID() {
        return ManagementFactory.getRuntimeMXBean().getPid();
    }

}

ApplicationPidFileWriter

官方文档参考:Process Monitoring

在任何 Java 工程中我们可以将 ManagementFactory 方式封装成一个工具类使用,如果我们基于 Spring Boot 搭建工程,也可使用其提供的机制进行获取 PID。

ApplicationPidFileWriter 是 Spring Boot 提供的一个 Listener,它可以在应用启动后把 PID 写入到指定的文件,具体实现方式如下:

修改启动类:

java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.ApplicationPidFileWriter;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplicationBuilder()
                .listeners(new ApplicationPidFileWriter())
                .sources(Application.class)
                .build(args);
        app.run(args);
    }
}

默认会将 pid 写入到 appplication.pid 文件中。

也可修改配置文件(以 application.properties 为例):

properties
1
2
3
4
# PID 写入的文件名
spring.pid.file=app.pid
# PID 写入失败是否抛出异常
spring.pid.fail-on-write-error=false

如此配置后,在启动 Spring Boot 工程后,会将当前 PID 写入到 spring.pid.file 指定的文件中。

JPS

JDK 提供了 jps 命令。(JDK 提供的工具,需在机器上安装 JDK 并正确配置环境变量)

直接在终端输入 jps,即可列出所有 Java 进程的 PID 及对应的进程名称。

PS

如果应用运行在 Linux 系统,同时机器未安装 JDK,那么可以通过 ps 命令配合表达式来查询指定进程的 PID:

shell
1
ps -ef | grep your-jar-name.jar

命令说明:

  • ps 是一个用于查询当前运行进程的命令
  • -efps 命令的选项,用于显示所有进程的详细信息,包括进程的用户、进程 ID(PID)、父进程 ID(PPID)、CPU 使用情况等。
  • | 是管道符号,用于将一个命令的输出作为另一个命令的输入。
  • grep 是一个用于在文本中搜索指定内容的命令。
  • your-jar-name.jar 是指要搜索的内容关键字

$!

如果应用运行在 Linux 系统,同时使用 shell 脚本启动应用,则可通过 $! 变量获取应用的 PID:

shell
1
nohup java -jar your-jar-name.jar & echo $! > app.pid

命令说明:

  • nohup:它会忽略 SIGHUP 信号(终端挂起信号),这样即使关闭终端,进程也会继续运行。
  • &:将命令置于后台运行。
  • echo $! > app.pid 将刚刚启动的进程 PID 写入到文件 app.pid 中。