13 07 2020

前言

JDK 的 bin 目录下有各种不同功能的小工具,包括编译、运行、部署、签名、调试、监控、运维等等。

为了在开发或者生产环境中能快速排查问题,我们需要掌握一些常用的工具。本文示例主要使用 jdk8,操作系统使用 linux。

基础故障处理工具

1. jps(JVM Process Status Tool):虚拟机进程状况工具

JDK 很多工具的名称都是参考 UNIX 命令的命名方式,jps 与 ps 命令类似,可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main() 函数所在的类)名称以及这些进程的本地虚拟机唯一 ID(LVMID,Local Virtual Machine Identifier)。

虽然其功能单一,但它是使用频率最高的 JDK 命令工具,因为其他工具大多需要输入 LVMID 来确定要监控哪一个虚拟机进程。

jps 命令格式:

  1. jps [ option ] [ hostid ]

jps 可以通过 RMI 协议查询开启了 RMI 服务的远程虚拟机进程状态,参数 hostid 为 RMI 注册表中注册的主机名。

jps 工具主要选项:

选项 作用
-q 只输出 LVMID,省略主类的名称
-m 输出虚拟机进程启动时传递给主类 main() 函数的参数
-l 输出主类的全名,如果进程执行的是 JAR 包,则输出 JAR 路径
-v 输出虚拟机进程启动时的 JVM 参数

jps 执行示例:

  1. jps -l
  2. 28664 sun.tools.jps.Jps
  3. 9660 /usr/local/projects/jar/xunlu-linkhelper.jar
  4. 2222 org.apache.zookeeper.server.quorum.QuorumPeerMain

2. jstat(JVM Statistics Monitoring Tool):虚拟机统计信息监视工具

jstat 是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类加载、内存、垃圾收集、即时编译等运行时数据,在没有 GUI 图形界面、只提供了纯文本控制台环境的服务器上,它是运行期定位虚拟机性能问题的常用工具。

jstat 命令格式:

  1. jstat [ option ] [ vmid ] [ 间隔时间/毫秒 ] [ 查询次数 ]

如果是本地虚拟机进程,VMID 与 LVMID 一致;如果是远程虚拟机进程,那 VMID 的格式为:

  1. [protocal:][//]lvmid[@hostname[:port]/servername]

jstat 工具主要选项:

选项 作用
-class 监视类加载、卸载数量、总空间以及类装载所耗费的时间
-gc 监视 Java 堆状况,包括 Eden 区、2个Survivor区、老年代、元空间等的容量,已用空间,垃圾收集时间合计等信息
-gccapacity 监视内容与 -gc 基本相同,但输出主要关注 Java 堆各个区域使用到的最大、大小空间
-gcutil 监视内容与 -gc 基本相同,但输出只要关注已使用空间占总空间的百分比
-gccause 与 -gcutil 功能一样,但是会额外输出导致上一次垃圾收集产生的原因
-gcnew 监视新生代垃圾收集状况
-gcnewcapacity 监视内容与 -gcnew 基本相同,输出主要关注使用到的最大、最小空间
-gcold 监视老年代垃圾收集状况
-gcoldcapacity 监视内容与 -gcold 基本相同,输出主要关注使用到最大、最小空间
-gcmetacapacity 输出元数据空间使用到的最大、最小空间
-compiler 输出即时编译器编译过的方法、耗时等信息
-printcompiler 输出已经被即时编译的方法

jstat 执行示例:

  1. jstat -gcutil 9660
  2. S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
  3. 99.83 0.00 16.79 67.22 95.24 92.41 20 0.920 3 0.250 1.170
  • S0、S1:两个 Survivor 区
  • E:新生代 Eden 区,使用了 16.79% 的空间
  • O:老年代(Old),使用了 67.22% 的空间
  • M:元数据空间,已使用了 95.24% 的空间
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

3. jinfo(Configuration Info for Java):Java 配置信息工具

jinfo 的作用是实时查看和调整虚拟机各项参数。

jinfo 命令格式:

  1. jinfo [ option ] [ pid ]

jinfo 工具主要选项

选项 作用
-flag [name] 输出指定 VM 标志的值
-flag [+ or -] [name] 启用或者禁用命名 VM 标志
-flag [name]=[value] 将命名 VM 标志设置为给定值
-flags 输出所有 VM 标志
-sysprops 输出所有虚拟机进程的系统属性

jinfo 执行示例:

  1. # 查询 CMSInitiatingOccupancyFraction 参数值
  2. jinfo -flag CMSInitiatingOccupancyFraction 9660
  3. -XX:CMSInitiatingOccupancyFraction=-1

4.jmap(Memory Map for Java):Java 内存映像工具

jmap 命令用于生成堆转储快照(一般称为 heapdump 或者 dump文件)。

jmap 的作用不仅仅是为了获取堆转储快照,它还可以查询 finalize 执行队列、Java 堆和方法区的详细信息,如空间使用率、当前用的是哪种垃圾收集器等。

jmap 命令格式:

  1. jmap [ option ] [ vmid ]

jmap 工具主要选项(部分功能在 windows 平台受限):

选项 作用
-dump 生成 Java 堆转储快照。格式为 -dump:[live,]format=b,file=,其中 live 自参数说明是否只 dump 出存活的对象
-finalizerinfo 显示在 F-Queue 中等待 Finalizer 线程执行 finalize 方法的对象。只在 Linux/Solaris 平台下有效
-heap 显示 Java 堆详细信息,如使用哪种回收器、参数配置、分代状况等。只在 Linux/Solaris 平台下有效
-histo 显示堆中对象统计信息,包括类、实例数量、合计容量
-clstats 显示类加载器统计信息
-F 当虚拟机进程对 -dump 选项没有响应时,可使用这个选项强制生成 dump 快照。只在 Linux/Solaris 平台下有效

jmap 执行示例:

  1. jmap -dump:format=b,file=test.bin 9660
  2. Dumping heap to /root/test.bin ...
  3. Heap dump file created

5.jhat(JVM Heap Analysis Tool):虚拟机堆转储快照分析工具

jhat 是 JDK 提供与 jmap 搭配使用的。

jhat 内置了一个微型的 HTTP/Web 服务器,生成堆转储快照的分析结果可以在浏览器中查看。

jhat 命令示例:

  1. jhat test.bin
  2. Reading from test.bin...
  3. Dump file created Wed Feb 17 16:30:52 CST 2021
  4. Snapshot read, resolving...
  5. Resolving 3712987 objects...
  6. Chasing references, expect 742 dots..............................
  7. Eliminating duplicate references.........................
  8. Snapshot resolved.
  9. Started HTTP server on port 7000
  10. Server is ready.

通过浏览器访问 http://localhost:7000/ 可以查看分析结果。

不过,分析 dump 文件一般不会在当前服务器上进行,且 jhat 的分析功能较为简陋,通常会使用更加专业的工具,如 Visual VM、Eclipse Memory Analyzer 等等。

6.jstack(Stack Trace for Java):Java 堆栈跟踪工具

jstack 命令是用于生成虚拟机当前时刻的线程快照(一般称为 threaddump 或者 Javacore文件)。

线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因,如线程死锁、死循环、请求外部资源导致的长时间挂起等,都是导致线程长时间停顿的常见原因。

线程出现停顿时通过 jstack 来查看各个线程的调用堆栈,就可以获知没有响应的线程到底在后台做了什么事情或者等待着什么资源。

jstack 命令格式:

  1. jstack [ option ] [vmid]

jstack 工具主要选项:

选项 作用
-F 当正常输出的请求不被响应时,强制输出线程堆栈
-l 除堆栈外,显示关于锁的附加信息
-m 如果调用到本地方法的话,可以显示 C/C++ 的堆栈

jstack 执行示例:

  1. jstack -l 9660
  2. 2021-02-17 16:42:04
  3. Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):
  4. "Attach Listener" #443 daemon prio=9 os_prio=0 tid=0x00007f4f0801a800 nid=0x4568 waiting on condition [0x0000000000000000]
  5. java.lang.Thread.State: RUNNABLE
  6. Locked ownable synchronizers:
  7. - None
  8. ......
延伸阅读
  1. JVM 运行时数据区域
  2. JVM 基础
  3. JVM 基础故障处理工具
发表评论