JVM调试
1.基本命令
命令 | 备注 |
---|---|
jps | 查看java进程pid |
jinfo -flags pid | 查看JVM基本信息 |
jmap -heap pid | 查看JVM堆信息 |
jstack pid | grep runnable|RUNNABLE | pid进程下的堆栈信息(比较多,建议重定向到文件中) |
jstat -gc pid 1000 3 | JVM统计信息,gc内存占用,gc时间,1000表示1000ms,3表示最新3行 |
jstat -gcutil pid 1000 3 | JVM统计信息,gc内存占用,gc时间,1000表示1000ms,3表示最新3行 |
jmap -histo:live pid | 查看堆内存中存活对象列表个数与内存占用(比较多建议重定向到文件中然后使用head -n 30 jmaplive.txt查看前30行,找出占用内存较多的对象) |
jmap -dump:live,format=b,file=mydump.hprof pid | 生成堆日志文件用于分析 |
jhat mydump.hprof | 分析堆日志文件,会开一个服务端默认端口为7000,可以使用-port参数指定端口(不好用) |
jvisualVm | 可视化jvm分析工具(有些JDK自带) |
visualVm | 可视化jvm分析工具(本地安装使用) |
JConsole | 可视化jvm分析工具(有些JDK自带) |
Mat | 可视化jvm分析工具(本地安装使用)(推荐使用)下载https://www.eclipse.org/downloads/download.php |
2.gc是否健康
(1)查看JVM运行时间
ps -p pid -o etime
(2)查看gc次数
root@27bfbc68c376:/# ps -p 1 -o etime
ELAPSED
56:10
root@27bfbc68c376:/# jstat -gcutil 1 1000 3
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.23 0.00 26.08 4.25 95.04 90.70 18 0.653 5 0.667 1.320
0.23 0.00 26.08 4.25 95.04 90.70 18 0.653 5 0.667 1.320
0.23 0.00 27.94 4.25 95.04 90.70 18 0.653 5 0.667 1.320
(3)根据运行时间计算GC平均时间
结论(百度所得,估计找到的都有所不同,YoungGc次数太少或者FullGc次数多,YoungGc时间长,多少都有点问题,内存溢出就可以用命令查看堆栈内存使用情况):
- YoungGC频率不超过2秒/次;
- 每次YoungGC的时间不超过15ms;
- FullGC频率尽可能完全杜绝;
3.如何分配堆空间
堆大小为2G即可,也可分配大一点,-Xms4096m,-Xmx6144m,-Xmn2304m,Xms为堆初始大小,Xmx为最大大小,Xmn是年轻代大小,Sun官方推荐配置为整个堆的3/8(Xms和Xmx建议一样大小)年轻代Eden大小:S0:S1=8:1:1(可以不配置);
4.分析内存泄漏
使用jmap命令生成JVMdump日志,用jhat、visualVm或者Mat(墙裂推荐)分析
工具 | 优点 | 缺点 |
---|---|---|
jhat | 直接在远程机器上运行 | 需要开放一个端口,生成内容比较难排查,需要熟悉OQL,比较慢 |
visualVm | 远程与本地均可使用,界面化展示,功能多样,实时性好 | 对于重写finalize方法造成的内存泄露找不到Gcroot难以排查代码,降低服务端性能 |
Mat | 界面化展示,分析有针对性,界面化展示 | 必须得导出相应JVM的进程dump文件,推荐使用 |
5.Mat使用
(1)下载https://www.eclipse.org/downloads/download.php
(2)修改MemoryAnalyzer.ini中-vm配置(只支持Java11及更高版本)
-vm
D:\env\jdk-11.0.17\bin\javaw.exe
(3)双击运行,打开dump文件
(4)内存泄漏报告
6.VisualVm使用
片转存中…(img-e0dStpEQ-1675770469398)]
[外链图片转存中…(img-KtdYLAIA-1675770469399)]