JVM监控诊断之命令行使用
Posted 编程小吉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM监控诊断之命令行使用相关的知识,希望对你有一定的参考价值。
JVM监控诊断
在刚开始学习Java的时候,我们肯定对
javac
和java
两个命令非常熟悉。但其实在JDK中,Oracle官方还给我们提供了许多辅助命令工具,也都在安装JDK的bin目录下,这些辅助命令工具大都是用来获取JVM不同方面、不同层次的信息,帮助开发人员能够更好的解决应用程序中出现的一些疑难杂症。
1.jps命令
jps(Java Process Status),用于查询正在运行的虚拟机进程或是Java应用程序进程
-
基本使用
🎈:左边是进程号,右边是进程名称
👉:这里显示的本地虚拟机进程ID,其实和本地操作系统的进程ID是一致的,都是唯一的。
👉:如果在Java进程启动时,使用了
-XX:-UserPerfData
参数,即关闭默认开启的UserPerfData参数的话,那么jps命令则无法探测该Java进程。 -
参数使用
-
jps -q
💡:只显示本地虚拟机进程ID
-
jps -l
💡:显示应用程序主类的全类名
-
jps -m
💡:显示虚拟机启动时,传递给各应用程序的参数
-
jps -v
💡:显示虚拟机启动时设置的JVM参数
-
jps -options -hostid
💡:显示远程主机上的Java虚拟机进程信息
-
2.jstat命令
jstat(Java Statistics Monitoring Tool),用于监视虚拟机各种运行状态信息,显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
-
基本参数
-
jstat -class
💡:显示类加载的相关信息,包括类的装载数量、类的卸载数量、类装载所消耗的时间等
-
jstat -gc
💡:显示与GC相关的堆区间信息,包括Eden区、Survivor区、老年代、永久代的总容量、已使用空间等信息
- S0C:第一个幸存者区的总大小,单位为字节
- S1C:第二个幸存者区的总大小,单位为字节
- S0U:第一个幸存者区的已使用大小,单位为字节
- S1U:第二个幸存者区的已使用大小,单位为字节
- EC:Eden区的总大小,单位为字节
- EU:Eden区的已使用大小,单位为字节
- OC:老年代的总大小,单位为字节
- OU:老年代的已使用大小,单位为字节
- MC:方法区的总大小,单位为字节
- MU:方法区的已使用大小,单位为字节
- CCSC:压缩类空间的总大小,单位为字节
- CCSU:压缩类空间的已使用大小,单位为字节
- YGC:从程序启动开始,发生Young GC的次数
- YGCT:Young GC的耗时,单位为秒
- FGC:从程序启动开始,发生Full GC的次数
- FGCT:Full GC的耗时,单位为秒
- GCT:从程序启动开始,所有GC发生的总耗时,单位为秒
-
jstat -gccapacity
💡:显示与GC相关的堆空间中各个区域的最大空间、最小空间等信息
-
jstat -gcutil
💡:显示与GC相关的堆空间中各个区域的已使用空间占比信息
-
jstat -gccause
💡:显示情况与上面的命令类似,不过会输出导致发生GC的原因
-
jstat -gcnew
💡:显示年轻代GC的垃圾回收信息
-
jstat -gcnewcapacity
💡:显示年轻代使用的最大空间、最小空间等信息
-
jstat -gcold
💡:显示老年代GC的垃圾回收信息
-
jstat -gcoldcapacity
💡:显示老年代使用的最大空间、最小空间等信息
-
jstat -gcpermcapacity
💡:显示永久代使用的最大空间、最小空间等信息
-
jstat -compiler
💡:显示JIT编译器编译过的方法、耗时等信息
-
jstat -printcompilation
💡:显示已经被JIT编译器编译的方法
-
-
附加参数
-
jstat -option -interval
💡:指定输出统计数据的间隔时间,单位为毫秒,也就是每隔多少毫秒打印一次信息
-
jstat -option -count
💡:指定输出统计数据的次数
-
jstat -option -t
💡:显示程序当前运行的总时间,单位为秒
-
jstat -option -h
💡:指定输出多少行数据时,输出一下表头信息
-
-
实际场景
判断是否出现内存溢出
- 在程序的运行过程中,在某段时间内使用jstat命令连续获取多行监控数据,计算这段时间中程序的运行时间以及总的发生GC的时间,然后进行对比。
- 如果GC发生的时间占据了程序运行总时间的90%以上,则说明很有可能要发生OOM异常。
判断是否出现内存泄露
- 在程序的运行过程中,在某段时间内使用jstat命令连续获取多行监控数据,然后取出老年代当前占用空间(OU)的最小值。
- 每隔一段时间就提取出上面提到的OU最小值,然后进行对比。如果发现该值在不断的上涨,这说明在进行GC时,很多存在于老年代的对象根本无法回收,所以也就有可能发生了内存泄露。
3.jinfo命令
jinfo(Configuration Info For Java),用于查看Java虚拟机的相关参数信息,也可用来调整Java虚拟机中的参数配置。
-
查看相关
-
java -XX:+PrintFlagsInital
💡:显示JVM启动时所有参数时的默认值
-
java -XX:+PrintFlagsFinal
💡:显示JVM启动时所有参数时的最终值
-
java -XX:+PrintCommandLineFlags
💡:显示JVM启动时被用户修改后的参数信息
-
jinfo -sysprops
💡:显示由System.getProperties()方法可以获取到的参数信息
-
jinfo -flags
💡:显示当前运行程序中JVM已设置的参数信息
-
jinfo -flag
💡:显示当前运行程序中JVM已设置的指定参数信息
-
-
设置相关
-
jinfo -flag +/-name
💡:对Boolean类型的JVM参数进行设置
-
jinfo -flag name=value
💡:对非Boolean类型的JVM参数进行设置
-
4.jmap命令
jmap(JVM Memory Map),可用于获取堆转储快照文件(dump文件),获取Java进程的内存使用情况,获取堆空间各个区域的使用情况,获取堆空间中对象的统计信息,获取类加载的信息等等。
-
基本参数
-
jmap -dump
💡:生成堆转储dump文件
-
jmap -heap
💡:显示整个堆空间的详细信息,包括GC的使用、堆的配置、内存的使用
-
jmap -histo
💡:显示堆空间中对象的统计信息,包括类、实例变量
-
jmap -permstat
💡:显示永久代的内存状态信息,仅在Linux/Solaris系统平台中有效
-
jmap -finalizerinfo
💡:显示正在等待Finalizer线程执行finalize方法的对象信息,仅在Linux/Solaris系统平台中有效
-
jmap -F
💡:强制执行命令,仅在Linux/Solaris系统平台中有效
-
jmap -J
💡:传递参数给jmap启动的JVM
-
-
具体使用
-
导出内存映像文件
Heap Dump又叫做堆转储文件,指的是某个Java进程在某个时间点的内存快照,内容主要包括所有的类信息、对象信息、垃圾回收器信息、线程栈帧和局部变量表等信息。
🎈:在生成该文件之前,通常会触发一次Full GC,并且生成的过程比较耗时。
手动生成方式
# 生成dump文件 jmap -dump:fromat=b,file=xxx.hprof <pid> # 生成dump文件(只包含存活的对象信息) jmap -dump:live,fromat=b,file=xxx.hprof <pid>
自动生成方式
# 在JVM启动参数设置中开启此功能,当程序发生OOM异常时,自动导出dump文件到指定位置 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/xxx.hprof
-
展示堆内存相关信息
# 堆空间各个区域的使用情况 jmap -heap <pid> # 堆空间中对象内存占用情况 jmap -histo <pid>
-
-
注意事项
- 由于jmap在执行时,会访问堆空间中的所有对象,所以为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有的线程停留在不改变堆中数据的状态。
- 如果某个线程长时间无法到达安全点,那么jmap在运行时将会一直等待。
5.jhat命令
jhat(JVM Heap Analysis Tool),可用于对堆转储快照文件(dump文件)进行分析,其内部内置了一个微型的HTTP服务器,以便将分析的结果以页面的形式呈现在浏览器上,我们可以通过访问本地7000端口进行查看。
-
基本参数
-
jhat -stack false|true
💡:显示或关闭对象分配调用栈跟踪
-
jhat -refs false|true
💡:显示或关闭对象引用跟踪
-
jhat -port
💡:设置jhat内置HTTP服务器的启动端口号
-
jhat -exclude
💡:指定执行对象查询时需要排除的数据成员
-
jhat -baseline
💡:指定一个基准堆转储文件
-
jhat -debug
💡:设置分析时所用debug的级别
-
jhat -version
💡:显示jhat的版本信息
-
jhat -J
💡:为jhat设置启动参数
-
-
注意事项
- 该命令在JDK9、JDK10中已被删除。
6.jstack命令
jstack(JVM Stack Trace),用于生成指定Java应用程序进程的某一时刻的线程快照,包含了当前线程正在执行方法的堆栈集合,可用于分析线程出现长时间阻塞等待的原因。
-
基本使用
-
参数使用
-
jstack -F
💡:当正常输出的请求不被响应时,强制输出线程堆栈信息
-
jstack -l
💡:额外显示关于锁的附加信息
-
jstack -m
💡:当程序调用本地方法时,额外显示C/C++的堆栈信息
-
7.jcmd命令
jcmd是一个多功能命令行工具,可以用来实现前面所描述的指令的大部分功能,比如:导出堆转储文件、查看内存使用情况、查看GC执行信息、查看JVM运行时间等等。
-
参数使用
-
jstack -l
💡:显示所有的JVM进程信息
-
jstack <进程ID> help
💡:显示指定进程所能够支持的所有命令
-
jstack <进程ID> <具体指令>
💡:显示指定进程使用指定指令后的输出信息
-
8.jstatd命令
-
在上面我们所描述的一些监控命令中,有一些是支持对远程计算机的应用程序进行监控的,比如:jps、jstat,但是它们还需要配合使用jstatd命令工具才能实现远程监控。
-
jstatd命令工具是一个RMI服务端程序,它的作用相当于代理服务器,用于建立本地计算机和远程计算机之间的通信桥梁。
以上是关于JVM监控诊断之命令行使用的主要内容,如果未能解决你的问题,请参考以下文章