生产环境中直接排查 JVM 的话,最简单的做法就是使用 JDK 自带的 6 个非常实用的命令行工具来排查。它们分别是:jps、jstat、jinfo、jmap、jhat 和 jstack,它们都位于 JDK 的 bin 目录下,可以使用命令行工具直接运行,其目录如下图所示:
![](https://static001.geekbang.org/infoq/17/17445a62c55db956ed03f980203063f3.webp?x-oss-process=image/resize,p_80/format,jpg)
接下来我们来看看这些工具的具体使用。
jps(虚拟机进程状况工具)
jps(JVM Process Status tool,虚拟机进程状况工具)它的功能和 Linux 中的 ps 命令比较类似,用于列出正在运行的 JVM 的 LVMID(Local Virtual Machine IDentifier,本地虚拟机唯一 ID),以及 JVM 的执行主类、JVM 启动参数等信息。语法如下:
![](https://static001.geekbang.org/infoq/72/720d404f138dc481b23ebce0056336df.webp?x-oss-process=image/resize,p_80/format,jpg)
使用实例:
![](https://static001.geekbang.org/infoq/9b/9ba17f1be137b67f97b243d65daec7ec.webp?x-oss-process=image/resize,p_80/format,jpg)
jstat(虚拟机统计信息监视工具)
jstat(JVM Statistics Monitoring Tool,虚拟机统计信息监视工具)用于监控虚拟机的运行状态信息。例如,我们用它来查询某个 Java 进程的垃圾收集情况,示例如下:
![](https://static001.geekbang.org/infoq/99/994035ffa85170f638c483ee1b1c3981.webp?x-oss-process=image/resize,p_80/format,jpg)
参数说明如下表所示:
![](https://static001.geekbang.org/infoq/43/43ceb23458d208c5cfd3a6b6ba7aa2ab.webp?x-oss-process=image/resize,p_80/format,jpg)
注意:年轻代的 Edem 区满了会触发 young gc,老年代满了会触发 old gc。full gc 指的是清除整个堆,包括 young 区 和 old 区。
jstat 常用的查询参数有:
![](https://static001.geekbang.org/infoq/98/98cfd3860f996e5d7849929b25ac37a3.webp?x-oss-process=image/resize,p_80/format,jpg)
jinfo(查询虚拟机参数配置工具)
jinfo(Configuration Info for Java)用于查看和调整虚拟机各项参数。语法如下:
![](https://static001.geekbang.org/infoq/9d/9df5bb2b6b834e2f1634023b4f463f5f.webp?x-oss-process=image/resize,p_80/format,jpg)
其中 45129 是使用 jps 查询的 LVMID。我们可以通过 jinfo -flag [+/-]name 来修改虚拟机的参数值,比如下面的示例:
![](https://static001.geekbang.org/infoq/43/433eb583790f6f74029ac69bb71643f7.webp?x-oss-process=image/resize,p_80/format,jpg)
jmap(堆快照生成工具)
jmap(Memory Map for Java)用于查询堆的快照信息。查询堆信息示例如下:
![](https://static001.geekbang.org/infoq/16/16926012c895fe8036a13a2d8d4d049b.webp?x-oss-process=image/resize,p_80/format,jpg)
我们也可以直接生成堆快照文件,示例如下:
![](https://static001.geekbang.org/infoq/99/99b5500ae20aebf3740594aa4bc415e4.webp?x-oss-process=image/resize,p_80/format,jpg)
jhat(堆快照分析功能)
jhat(JVM Heap Analysis Tool,堆快照分析工具)和 jmap 搭配使用,用于启动一个 web 站点来分析 jmap 生成的快照文件。执行示例如下:
上述信息表示 jhat 启动了一个 http 的服务器端口为 7000 的站点来展示信息,此时我们在浏览器中输入:http://localhost:7000/,会看到如下图所示的信息:
![](https://static001.geekbang.org/infoq/52/522f40308f7059aeddabcb869f0b4875.webp?x-oss-process=image/resize,p_80/format,jpg)
jstack(查询虚拟机当前的线程快照信息)
jstack(Stack Trace for Java)用于查看当前虚拟机的线程快照,用它可以排查线程的执行状况,例如排查死锁、死循环等问题。
比如,我们先写一段死锁的代码:
![](https://static001.geekbang.org/infoq/72/72d2f5a09e7fb2a7871d6ec7b58f7719.webp?x-oss-process=image/resize,p_80/format,jpg)
以上程序的执行结果如下:
![](https://static001.geekbang.org/infoq/d1/d119015bdc125416fff3de01e6e0f44c.webp?x-oss-process=image/resize,p_80/format,jpg)
此时我们使用 jstack 工具打印一下当前线程的快照信息,结果如下:
![](https://static001.geekbang.org/infoq/6f/6f98c195b811a28f0f54f6b4a61a6bcc.webp?x-oss-process=image/resize,p_80/format,jpg)
从上述信息可以看出使用 jstack ,可以很方便地排查出代码中出现“deadlock”(死锁)的问题。
![](https://static001.geekbang.org/infoq/62/62e1c66b7ebe4ae627c388db8f4eef36.png)