概述
- jps将打印所有正在运行的 Java 进程。
- jstat允许用户查看目标 Java 进程的类加载、即时编译以及垃圾回收相关的信息。常用于检测垃圾回收问题以及内存泄漏问题。
- jmap允许用户统计目标 Java 进程的堆中存放的 Java 对象,并将它们导出成二进制文件。
- jinfo将打印目标 Java 进程的配置参数,并能够改动其中 manageabe 的参数。
- jstack将打印目标 Java 进程中各个线程的栈轨迹、线程状态、锁状况等信息。它还将自动检测死锁。
- jcmd则是一把瑞士军刀,可以用来实现前面除了jstat之外所有命令的功能。
jps
命令格式:jps [options ] [ hostid ]
[options]选项 :
-q:仅输出VM标识符,不包括classname,jar name,arguments in main method
-m:输出main method的参数
-l:输出完全的包名,应用主类名,jar的完全路径名
-v:输出jvm参数
-V:输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件
[hostid]:
[protocol:][[//]hostname][:port][/servername]
命令的输出格式 :
lvmid [ [ classname| JARfilename | “Unknown”] [ arg ] [ jvmarg ] ]
当获得 Java 进程的进程 ID 之后,我们便可以用接下来介绍的各项监控及诊断工具了。
jstat
命令格式:
jstat generalOptions
常规选项有-help
显示帮助信息。-options
显示静态选项列表
➜ ~ jstat -options
-class
-compiler
-gc
-gccapacity
-gccause
-gcmetacapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcutil
-printcompilation
在这些子命令中,
-class将打印类加载相关的数据,
-compiler和-printcompilation将打印即时编译相关的数据。
剩下的都是以-gc为前缀的子命令,它们将打印垃圾回收相关的数据。
jstat outputOptions [-t] [-h lines] vmid [interval [count] ]
- outputOptions:
**jstat -options**
命令输出的子命令 -t
将时间戳列显示为输出的第一列。时间戳是自目标JVM启动时间以来的时间。-h _n_
每个_n_
样本(输出行)显示一个列标题,其中_n_
是一个正整数。默认值为0
,它显示数据第一行的列标题。_vmid_
虚拟机标识符,它是指示目标JVM的字符串。请参阅虚拟机标识符。_interval_
采样间隔,以指定单位,秒(s)或毫秒(ms)为单位。默认单位是毫秒。必须是一个正整数。指定后,该jstat
命令将在每个间隔产生其输出。_count_
要显示的样本数。缺省值是infinity,这将导致jstat
命令显示统计信息,直到目标JVM终止或jstat
命令终止为止。该值必须是一个正整数。# Usage: jstat -outputOptions [-t] [-hlines] VMID [interval [count]] $ jstat -gc 22126 1s 4 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT 17472,0 17472,0 0,0 0,0 139904,0 47146,4 349568,0 21321,0 30020,0 28001,8 4864,0 4673,4 22 0,080 3 0,270 0 0,000 0,350 17472,0 17472,0 420,6 0,0 139904,0 11178,4 349568,0 21321,0 30020,0 28090,1 4864,0 4674,2 28 0,084 3 0,270 0 0,000 0,354 17472,0 17472,0 0,0 403,9 139904,0 139538,4 349568,0 21323,4 30020,0 28137,2 4864,0 4674,2 34 0,088 4 0,359 0 0,000 0,446 17472,0 17472,0 0,0 0,0 139904,0 0,0 349568,0 21326,1 30020,0 28093,6 4864,0 4673,4 38 0,091 5 0,445 0 0,000 0,536
jmap
```shell ➜ ~ jmap -options Usage: jmap [option]
jmap [option](to connect to running process)
jmap [option] [server_id@](to connect to a core file)
(to connect to remote debug server)
where
我们通常会利用jmap -dump:live,format=b,file=filename.bin
命令,将堆中所有存活对象导出至一个文件之中。
:::warning 由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。上一小节的jstat则不同。这是因为垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。 :::
jmap(以及接下来的jinfo、jstack和jcmd)依赖于 Java 虚拟机的Attach API,因此只能监控本地 Java 进程。一旦开启 Java 虚拟机参数DisableAttachMechanism(即使用参数-XX:+DisableAttachMechanism),基于 Attach API 的命令将无法执行。反过来说,如果你不想被其他进程监控,那么你需要开启该参数。
jinfo
jinfo命令(帮助文档)可用来查看目标 Java 进程的参数,如传递给 Java 虚拟机的-X(即输出中的 jvm_args)、-XX参数(即输出中的 VM Flags),以及可在 Java 层面通过System.getProperty获取的-D参数。
jinfo还可以用来修改目标 Java 进程的“manageable”虚拟机参数。举个例子,我们可以使用jinfo -flag +HeapDumpAfterFullGC 命令,开启所指定的 Java 进程的HeapDumpAfterFullGC参数。
你可以通过下述命令查看其他 “manageable” 虚拟机参数:java -XX:+PrintFlagsFinal -version | grep manageable
jstack
jstack命令(帮助文档)可以用来打印目标 Java 进程中各个线程的栈轨迹,以及这些线程所持有的锁。
应用场景:死锁检测
jstack不仅会打印线程的栈轨迹、线程状态(BLOCKED)、持有的锁(locked …)以及正在请求的锁(waiting to lock …),而且还会分析出具体的死锁。
jcmd
可以直接使用jcmd命令(帮助文档),来替代前面除了jstat之外的所有命令