Jvm监控主要针对内存、线程、CPU、类等使用状况进行监控
自带监控性能分析工具
https://docs.oracle.com/javase/8/docs/technotes/tools
D:\jdk1.8.0_91\bin
jps(虚拟机进程状况工具)
jps -l:查看当前虚拟机所有的进程
jstat(统计信息监视工具)
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
jstat[ -命令选项 ] [ vm进程ID ] 间隔时间(单位毫秒) 查询次数:查看堆内存各部分以及加载类的使用量
类加载统计
Loaded:加载class的数量
Bytes:所占用空间大小
Unloaded:未加载数量
Bytes:未加载占用空间
Time:时间
C:\Users\Administrator>jstat -class 16740
Loaded Bytes Unloaded Bytes Time
13149 23152.1 9 8.1 11.70
编译统计
Compiled:编译数量
Failed:失败数量
Invalid:不可用数量
Time:时间
FailedType:失败类型
FailedMethod:失败的方法
C:\Users\Administrator>jstat -compiler 16740
Compiled Failed Invalid Time FailedType FailedMethod
6967 0 0 3.19 0
垃圾回收统计
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
C:\Users\Administrator>jstat -gc 16740
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
18432.0 5120.0 0.0 4992.0 247296.0 164600.3 219136.0 31718.6 66264.0 61674.8 9432.0 8535.0 17 0.531 3 0.475 1.006
新生代垃圾回收统计
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
TT:对象在新生代存活的次数
MTT:对象在新生代存活的最大次数
DSS:期望的幸存区大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
C:\Users\Administrator>jstat -gcnew 16740
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
18432.0 5120.0 0.0 4992.0 9 15 18432.0 247296.0 173011.9 17 0.531
新生代内存统计
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大幸存1区大小
S0C:当前幸存1区大小
S1CMX:最大幸存2区大小
S1C:当前幸存2区大小
ECMX:最大伊甸园区大小
EC:当前伊甸园区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数
C:\Users\Administrator>jstat -gcnewcapacity 16740
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
86016.0 1369088.0 337920.0 456192.0 18432.0 456192.0 5120.0 1368064.0 247296.0 17 3
老年代垃圾回收统计
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
C:\Users\Administrator>jstat -gcold 16740
MC MU CCSC CCSU OC OU YGC FGC FGCT GCT
66264.0 61674.8 9432.0 8535.0 219136.0 31718.6 17 3 0.475 1.006
老年代内存统计
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:老年代大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
C:\Users\Administrator>jstat -gcoldcapacity 16740
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
172032.0 2739200.0 219136.0 219136.0 17 3 0.475 1.006
元数据空间统计
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
C:\Users\Administrator>jstat -gcmetacapacity 16740
MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT
0.0 1105920.0 66264.0 0.0 1048576.0 9432.0 17 3 0.475 1.006
总结垃圾回收统计
S0:幸存1区当前使用比例
S1:幸存2区当前使用比例
E:伊甸园区使用比例
O:老年代使用比例
M:元数据区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间
C:\Users\Administrator>jstat -gcutil 16740
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 97.50 77.37 14.47 93.07 90.49 17 0.531 3 0.475 1.006
JVM编译方法统计
Compiled:最近编译方法的数量
Size:最近编译方法的字节码数量
Type:最近编译方法的编译类型
Method:方法名标识
C:\Users\Administrator>jstat -printcompilation 16740
Compiled Size Type Method
6967 196 1 sun/management/MappedMXBeanType$CompositeDataMXBeanType toJavaTypeData
jinfo(java配置信息工具)
jinfo -flag 要查看的值 进程号
jinfo -flags 进程号
使用jinfo出现问题
C:\Users\62350>jinfo -flags 37028
Attaching to process ID 37028, please wait...
Error attaching to process: java.lang.RuntimeException: can't determine target's VM version : field "_reserve_for_allocation_prefetch" not found in type Abstract_VM_Version
sun.jvm.hotspot.debugger.DebuggerException: java.lang.RuntimeException: can't determine target's VM version : field "_reserve_for_allocation_prefetch" not found in type Abstract_VM_Version
at sun.jvm.hotspot.HotSpotAgent.setupVM(HotSpotAgent.java:435)
at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:305)
at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
at sun.jvm.hotspot.tools.JInfo.main(JInfo.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.tools.jinfo.JInfo.runTool(JInfo.java:108)
at sun.tools.jinfo.JInfo.main(JInfo.java:76)
Caused by: java.lang.RuntimeException: can't determine target's VM version : field "_reserve_for_allocation_prefetch" not found in type Abstract_VM_Version
at sun.jvm.hotspot.runtime.VM.<init>(VM.java:291)
at sun.jvm.hotspot.runtime.VM.initialize(VM.java:370)
at sun.jvm.hotspot.HotSpotAgent.setupVM(HotSpotAgent.java:431)
... 11 more
原因:本地jdk版本是1.8,而启动的服务的jdk版本是11
jmap(内存映射工具)
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html
生成java应用程序的堆快照和对象的统计信息
映射堆快照:jmap -heap 进程ID
抓取堆内存:
1. 生成hprof文件并下载到本地;
2. MAT分析插件工具:eclipse插件,idea需要安装
安装地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation
下载Windows(x86_64)的版本
jhat(虚拟机堆转储快照分析工具)
Java Virtual Machine Heap Analysis Tool,用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果。
jhat命令与jmap搭配使用,分析jmap生成的堆转储快照。jhat会解析dump出来的文件,并在本地启动一个web服务器,默认情况下web服务器的端口是7000。
在实际工作中,一般不会去直接使用jhat命令来分析demp文件,原因如下:
- 一般不会在部署应用程序的服务器上直接分析dump文件,即使可以这样做,也会尽量将dump文件拷贝到其他机器上进行分析,因为分析工作是一个耗时且消耗硬件资源的过程,既然都要在其他机器上进行,就没必要受到命令行工具的限制了;
- jhat的分析功能相对来说很简陋,VisualVM以及专门分析dump文件的Eclipse Memory Analyzer、IBM HeapAnalyzer等工具,都能实现比jhat更强大更专业的分析功能。
jstack(堆栈异常跟踪工具)
java虚拟机自带的堆栈跟踪工具,用于生成JVM当前时刻的线程快照。
线程快照是指当前JVM中每一条线程正在执行的方法堆栈的集合,主要目的就是查看定位当前线程长时间停顿的原因,例如死锁,死循环,长时间请求其他资源等,若Java线程崩溃生成core文件,可使用jstack来获取core文件的Java stack和native stack信息,从而分析Java线程崩溃原因
D:\jdk1.8.0_91\bin>jstack
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F [-m] [-l] <pid>
(to connect to a hung process)
jstack [-m] [-l] <executable> <core>
(to connect to a core file)
jstack [-m] [-l] [server_id@]<remote server IP or hostname>
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
//-F 当执行jstack -l [pid]没有响应时强制打印栈信息,或者jstack无响应时,强制jstack
//-m 打印Java和native的所有栈信息,打印JVM堆栈和native栈帧
//-l 打印关于锁的附加信息,会使JVM停顿好久,例如 jstack -l 21023 > /tmp/deadlock.txt
jvisualvm调优工具
jdk自带的监控工具,提供针对内存、CPU、线程等相关指标监控功能,能够满足基本的监控需求。
安装visual GC插件
选择与jdk版本符合的插件:VisualVM: Plugins Centers
本地jvisualvm可以通过jstatd远程监控GC
jsonsole调优工具
监控java程序堆空间的使用情况,主要包含堆空间的使用情况、线程数量、类、CPU占用率
Arthas
Alibaba的jvm调优工具,arthas.aliyun.com/doc/
trace命令:来追踪方法调用,官方对其功能的介绍如下:
追踪方法内部调用路径,并输出方法路径上的每个节点上耗时,trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
dashboard:可以全局查看系统运行状况,查看整个进程的运行情况,线程,内存,GC,运行环境信息
thread 线程ID:可以定位到该线程的问题
thread -b:可以查看线程死锁
jad 类的全路径名:可以反编译,方便查看线上代码是否是正确版本
ognl:查看线上系统变量的值,也可以修改变量的值
GCEasy
GC日志分析工具:Universal JVM GC analyzer - Java Garbage collection log analysis made easy
也可以上传log文件
生成log文件
jvm内存区域大小
JVM memory size展示了年轻代、老年代、元空间。JVM给分配的大小和程序运行过程中使用的峰值大小。
通过分析这些信息,可以片段是否做以下几件事情:
- 若年轻代和老年代峰值远远小于分配的大小,可以通过修改(-Xms、-Xmx、-Xmn…)来适当的减小内存设置。
- 若老年代的峰值一直小于老年代申请内存,可以调整年轻代和老年代的比例(-XX:NewSize、-XX:MaxNewSize、-XX:SurvivorRatio=8),稍微多分点空间给年轻代。
- 是否需要修改元空间(XX:MetaspaceSize,-XX:MaxMetaspaceSize)相关设置。
- 年轻代,老年代属于堆区,元空间属于非堆区
Key Performance Indicators(关键性能指标)
Throughput:吞吐量
Latency:响应时间
Avg Pause GC Time:平均GC时间
Max Pause GC TIme:最大GC时间
这部分展示了GC吞吐量(应用程序线程用时占程序总用时的比例,越高越好),每次GC的平均耗时(建议控制在50ms以下),GC最长耗时,每个时间段的GC次数及占比信息。
可以分析下面几个问题:
- 吞吐量吞吐量越高越好。
- 每次GC的平均耗时越小越好,建议50ms以下。
- GC最长耗时越小越好。若项目的任何请求不超过10秒,那么GC最长耗时就不能超过10秒。
根据内存调优准则,以上这三个优化指标,最多只能三者取其二:
- 想要比较好的吞吐量和延迟,就需要在CPU消耗有所牺牲
- 想要比较好的吞吐量和CPU消耗,就需要在延迟上有所牺牲
- 想要比较好的延迟和CPU消耗,就需要在吞吐量上有所牺牲
Interactive Graphs(交互圈)
根据左面圈住的地方可以切换图表
Heap after GC:记录GC之后堆的使用情况,堆是用来存储对象的,随着GC的进行,垃圾回收器把对象都回收掉了,因此堆的大小逐渐增大。
Heap before GC:GC前堆的情况,可以看出随着程序的运行,堆使用率越来越高,堆被对象占用的内存越来越大。
GC Duration:GC持续时间,STW阶段花费的时间。
Reclaimed Bytes:GC回收掉的垃圾对象的内存大小
Young Gen:年轻代堆的使用情况,before GC会逐渐增大,表示年轻代中对象越来越多,GC发生后,年轻代中对象就会减少,表示after GC的内存变化趋势。
Old Gen:老年代堆的使用情况。
Meta Space:元空间的使用情况
A & P:每次GC的时候堆内存分配和晋升情况。其中红色的线表示每次GC的时候年轻代里面有多少内存(对象)晋升到了老年代。
GC Statistics(GC统计信息)
显示一些GC的统计信息。每种GC总共回收了多少内存、总共用了多长时间、平均时间、以及每种GC单独统计的信息。
Object Stats(对象的一些统计信息)
total created bytes:总共创建的对象数
total promoted bytes:总共升级的对象数
avg creation rate:平均字节创建率
avg promotion rate:平均字节升级率
GC Causes(GC的原因信息)
Memory Leak
内存泄漏的日志信息。此处可以诊断8种OOM中的5种(Java堆空间溢出、超过GC开销限制、请求的数组大小超过VM限制、Permgen空间、Metaspace)。