JDK8
在JDK安装目录下的bin文件夹,有一些辅助命令行工具,通常用来获取JVM的信息或者监控JVM,在排查性能问题方面是非常好用的工具。以Centos7.9系统下的openJDK1.8.0_222为例(不同大版本的JDK命令的参数会有差异,不同操作系统也有差异),如下图:
其中常用的有jps、jstat、jinfo、jmap、jstack、jcmd、jconsole等等。
jps
简介
jps(JVM Process Status)命令用于查看系统内所有的JVM进程,可根据参数选项指定是否显示JVM的执行主类[包含main()方法的类],以及进程的本地JVMID,对于本地JVM进程来说,进程的本地JVMID与操作系统的进程ID(ps命令查看)是一致的。它就是Java提供的一个显示当前所有Java进程pid的命令,和ps命令很相似。
注意:它只能看当前系统登录用户的jvm进程。
用法
jps [option] [hostid]
option | 用途 |
-q | 只输出LVMID(本地虚拟机唯一ID,一般是进程ID),省略主类名称 |
-m | 输出JVM进程启动时传递给主类main()函数的参数 |
-l | 输出主类的全称,如果进程执行的是jar包,则输出jar路径 |
-v | 输出JVM进程启动时的JVM参数 |
hostid是RMI服务注册表中注册的主机名,可以不写,不写就是查询本机的。
案例
# 输出jvm启动参数和main的参数
jps -lmv
# 第一列为jvmid,也就是pid
# 第二列是主类全称或jar路径
# 第三列是传给main方法的参数
# 第四列是jvm参数
jstat
简介
jstat(JVM Statistics Monitoring Tool)用于收集JVM各方面的运行数据,显示本地或远程JVM进程中的类装载、内存、垃圾收集、JIT编译等运行数据。常用于检测垃圾回收问题以及内存泄漏问题。
用法
# 查看option
jstat -options
jstat -<option>[-t] [-h<lines>] <vmid>[<interval>[<count>]]
选项 | 用途 |
-class | 监视类装载、卸载数量、总空间以及类装载所耗费的时间 |
-compiler | 输出JIT编译器编译过的方法、耗时等信息 |
-gc | 监视Java堆状况,包括Eden区,两个survivor区、老年代、方法区等容量、已用空间、gc时间合计等信息 |
-gccapacity | 监视与-gc相同,侧重点在于Java堆各个区域使用到的最大、最小空间 |
-gcmetacapacity | 监视元数据区gc情况 |
-gcnew | 监视新生代gc情况 |
-gcnewcapacity | 与-gcnew相同,侧重于使用到的最大、最小空间 |
-gcold | 监视老年代gc情况 |
-gcoldcapacity | 与-gcold相同,侧重于使用到的最大、最小空间 |
-gcutil | 与-gc基本相同,输出的是已使用空间占总空间的百分比 |
-gccause | 与-gcutil一样,但会额外输出导致上一次GC产生的原因 |
-printcompilation | 输出被JIT编译的方法 |
[-t]参数,可以在输出信息前加上一个Timestamp列,显示程序的运行时间。
[-h]参数,可以在输出一定行数的数据后输出一个表头信息,方便观察。
[interval]参数,指定输出统计数据的周期,单位支持秒(s),毫秒(ms),默认单位为毫秒,相当于查询间隔时间。
[count]参数,指定查询的总次数。
可以分析比较Java进程的启用时间以及总GC时间(GCT列),或者两次测量的间隔时间以及总GC时间的增量,来得出GC时间占运行时间的比例。如果该比例超过20%,说明目前堆的压力较大;如果该比例超过90%,则说明堆里几乎没有可用空间,一直在GC但是没用,随时可能抛出OOM异常。
案例
一般先用jps查出pid,再使用jstat监控。
# 先查询pid,为2205978
jps
# 每隔一秒打印一次,打印10次,加上时间戳,每隔5行打印一次表头,并输出到stat.log文件中
jstat -gc -t -h5 2205978 1000 10 > stat.log
列 | 含义 |
S0C | 新生代第一个survivor区的容量,单位为字节 |
S1C | 新生代第二个survivor区的容量,单位为字节 |
S0U | 新生代第一个survivor区的已使用空间,单位为字节 |
S1U | 新生代第二个survivor区的已使用空间,单位为字节 |
EC | 新生代Eden区容量,单位为字节 |
EU | 新生代Eden区已使用空间,单位为字节 |
OC | 老年代容量,单位为字节 |
OU | 老年代已使用空间,单位为字节 |
MC | 元数据区容量 |
MU | 元数据区已使用空间 |
CCSC | 压缩类空间总容量 |
CCSU | 压缩类空间已使用空间 |
YGC | 从应用程序启动到采样时youngGC次数 |
YGCT | 从应用程序启动到采样时youngGC消耗的时间,单位为秒 |
FGC | 从应用程序启动到采样时fullGC次数 |
FGCT | 从应用程序启动到采样时fullGC消耗的时间,单位为秒 |
GCT | 从应用程序启动到采样时GC用的总时间,单位为秒 |
jstatd
简介
jstat只涉及监控本机的Java应用程序,jstatd是一个RMI服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd服务器将本机的Java应用程序信息传递到远程计算机。它需要rmi相关的权限,一般不使用,了解即可。
用法
jstatd [-nr] [-p port] [-n rminame]
jinfo
简介
jinfo(Configuration Info for Java)可用于查看和调整JVM的配置参数。如果想要知道未被显示指定的参数的系统默认值,可以使用这个命令。
其次就是在程序运行时可以修改部分参数,并使之立即生效。但是不是所有参数都支持运行时修改,只有被标记为manageable的参数可以被实时修改。使用下面的命令查看被标记为manageable的参数。
java -XX:+PrintFlagsFinal -version | grep manageable
用法
jinfo [options] pid
选项 | 说明 |
空 | 输出全部参数和系统属性 |
-flag <name> | 输出名称为name的参数 |
-flag [+-]<name> | 开启(+)或关闭(-)对应名称的参数,被标记为management才可以生效 |
-flag <name>=<value> | 指定名称为name的参数值为value |
-flags | 输出全部参数 |
-sysprops | 输出系统属性,相当于Java里输出System.getProperties() |
案例
# 先使用jps查出pid,2205978
jps -l
# 查看所有参数和系统属性,参数为VM Flags部分,系统属性为Java System Properties部分
jinfo 2205978
# 查看所有参数
jinfo -flags 2205978
# 查看所有属性
jinfo -sysprops 2205978
# 查看某个参数
jinfo -flag MaxHeapSize 2205978
jinfo -flag PrintGC 2205978
# 设置参数开启、关闭,bool类型的可以用+、-操作,下面为开启类的直方图统计
jinfo -flag +PrintClassHistogram 2205978
jinfo -flag -PrintClassHistogram 2205978
# 将MaxHeapFreeRatio 调整为80,默认是100
jinfo -flag MaxHeapFreeRatio 80 28914
# 查看-XX类型参数的初始值
java -XX:+PrintFlagsInitial
# 查看所有-XX类型参数
java -XX:+PrintFlagsFinal
# 查看被用户或jvm设置过的详细的-XX类型的参数 的名称和值
java -XX:+PrintCommandLineFlags
jmap
简介
jmap(JVM Memory Map)用于生成JVM的内存转储快照,生成堆dump文件且可以查询finalize执行队列,以及Java堆与元空间的一些信息。除此之外,它还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。
注:jmap导出的快照是在线程运行到安全点处导出的。
用法
jmap <options> <pid>
jmap <options> <executable <core>>
jmap <options> [server_id@]<remote server IP or hostname>
选项 | 用途 |
-clstats | 打印类加载的统计信息 |
-finalizerinfo | 打印等待终结(执行finalize方法)的对象信息,即在finalizer队列中的对象 |
-heap | 打印java堆的简要信息 |
-histo | 统计堆中java对象的直方图 |
-histo:live | 统计堆中存活java对象的直方图 |
-dump:<dump-options> | dump java堆信息 |
-F | 当进程对-dump:<dump-options>或者-histo无响应时,会强制生成dump文件,Linux下有效 |
选项 | 用途 |
live | 仅dump堆中存活的对象,不写此选项则dump堆中所有对象 |
format=b | 二进制格式 |
file=<file> | dump到指定文件中 |
案例
# 先用jps查出pid,2205978
jps -l
# 打印堆的简略信息
jmap -heap 2205978
# 打印类加载的统计信息
jmap -clstats 2205978 > clstats.log
# 打印直方图
jmap -histo 2205978 > histo.log
# 以二进制格式dump堆中存活的对象,这个文件需要用专门的工具分析
jmap -dump:live,format=b,file=heap.bin 2205978
当因为内存泄露出现OOM错误时,需要在此时自动dump内存,用来分析当时的内存状况,可以在重启应用程序时JVM参数添加【-XX:+HeapDumpOnOutOfMemoryError】、【-XX:HeapDumpPath=./dump.bin】,dump路径可以定义,下次出现OOM则可以自动dump。
jstack
简介
jstack(JVM Stack Trace)用于生成JVM指定进程当前时刻的线程快照(Thread Dump),方便用户跟踪JVM堆栈信息。线程快照就是当前JVM内指定进程的每一条线程正在执行的方法堆栈的集合。
生成线程快照的作用是可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题,这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用jstack显示各个线程调用的堆栈情况。
线程快照中的状态
状态 | 含义 |
DeadLock | 死锁 |
Waiting on Condition | 条件等待 |
Waiting on monitor entry | 等待获取监视器 |
Blocked | 被阻塞 |
Runnable | 运行中 |
Suspend | 暂停 |
TIMED_WAITING、Object.wait() | 等待中 |
Parked | 停止 |
表中标红的部分需要重点关注,有可能是导致引用程序卡死的原因。
用法
jstack [-l] <pid>
jstack -F [-m] [-l] <pid>
jstack [-m] [-l] <executable> <core>
jstack [-m] [-l] [server_id@]<remote server IP or hostname>
选项 | 用途 |
-F | 当jstack <pid>无响应时,强制输出线程的dump信息 |
-l | 除了打印线程堆栈,还打印关于锁的附加信息 |
-m | 打印java和本地方法的栈帧(混合模式) |
案例
# 查出pid,2205978
jps
# 打印堆栈
jstack 2205978 > stack.log
jcmd
简介
在JDK1.7以后,新增了一个命令行工具jcmd。它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能,比如用它来导出堆、内存使用、查看Java进程、导出线程信息、执行GC、JVM运行时间等。
用法
jcmd #和jps -lm类似
jcmd -l #和jcmd作用相同
# 查看command
jcmd <pid> help
jcmd <pid | mainclass |jar> <options> # 当pid=0时,命令会发给所有的jvm
# 替代其他命令
jcmd <pid> GC.heap_dump #和jmap -dump <pid> 类似
jcmd <pid> GC.class_histogram #和jmap -histo <pid> 类似
jcmd <pid> Thread.print #和jstack <pid> 类似
jcmd <pid> VM.system_properties #和jinfo -sysprops <pid> 类似
jcmd <pid> VM.flags #和jinfo -flags <pid> 类似
...
选项 | 用途 |
command | 可以是所有的命令,用jcmd <pid> help查看所有支持的command |
PerfCounter.print | 打印当前进程的性能计数器 |
-f file | 从指定的文件读取command并执行 |
案例
# 查看pid 2205978
jcmd -l
# 查看command
jcmd 2205978 help
# 导出堆到文件里
jcmd 2205978 GC.heap_info > heap.log
# 打印其他参数
jcmd 2205978 VM.uptime
jcmd 2205978 VM.flags
jcmd 2205978 GC.class_histogram -all
# 打印性能计数器
jcmd 2205978 PerfCounter.print