JVM常见线上问题 → CPU 100%、内存泄露 问题排查

前言后文会从 windows、linux 两个系统来做示例展示,有人会有疑问了:为什么要说 Windows 版的 ? 目前市面上还是有很多 Windows 服务器的,应用于传统行业、政府结构、医疗行业 等等;两个系统下的情况都演示下,有备无患
后文中用到了两个工具:Processor Explorer、MAT,它们是什么,有什么用,怎么用,本文不做介绍
cpu 100%下面的示例中,cpu 的占有率没到 100%,只是比较高,但是排查方式是一样的,希望大家不要钻牛角尖
Windows
1、找到 cpu 占有率最高的 JAVA 进程号

JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
PID: 20260
2、根据进程号找到 cpu 占有率最高的线程号
双击刚刚找到的 java 进程
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
线程号: 15900 ,转成十六进制: 3e1c
3、利用 jstack 生成虚拟机中所有线程的快照
命令: jstack -l {pid} > {path}
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
文件路径: D:20260.stack
4、线程快照分析
我们先浏览下快照内容
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
内容还算比较简洁,线程快照格式都是统一的,我们以一个线程快照简单说明下
"main" #1 prio=5 os_prio=0 tid=0x0000000002792800 nid=0x3e1c runnable [0x00000000025cf000]
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
我们前面找到占 cpu 最高的线程号: 15900,十六进制: 3e1c,用 3e1c 去快照文件里面搜一下
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
自此,找到问题
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
Linux
排查方式与 Windows 版一样,只是命令有些区别
1、找到 cpu 占有率最高的 java 进程号
使用命令: top -c 显示运行中的进程列表信息, shift + p 使列表按 cpu 使用率排序显示
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
PID = 2227 的进程,cpu 使用率最高
2、根据进程号找到 cpu 占有率最高的线程号
使用命令: top -Hp {pid} ,同样 shift + p 可按 cpu 使用率对线程列表进行排序
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
PID = 2228 的线程消耗 cpu 最高,十进制的 2228 转成十六进制 8b4
3、利用 jstack 生成虚拟机中所有线程的快照
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
4、线程快照分析
分析方式与 Windows 版一致,我们可以把 2227.stack 下载到本地进行分析,也可直接在 Linux 上分析
在 Linux 上分析,命令: cat 2227.stack |grep '8b4' -C 5
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
【JVM常见线上问题 → CPU 100%、内存泄露 问题排查】至此定位到问题
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
不管是在 Windows 下,还是在 Linux 下,排查套路都是一样的
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
内存泄露同样的,Windows、Linux 各展示一个示例
Windows
1、找到内存占有率最高的进程号 PID
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
第一眼看上去, idea 内存占有率最高,因为我是以 idea 启动的 java 进程;idea 进程我们无需关注,我们找到内存占有率最高的 java 的 PID: 10824
2、利用 jmap 生成堆转储快照
命令: jmap -dump:format=b,file={path} {pid}
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
dump 文件路径: D:heapdump_108244.hprof
3、利用 MAT 分析 dump 文件
MAT:Memory Analyzer Tool,是针对 java 的内存分析工具;下载地址:
JVM常见线上问题 → CPU 100%、内存泄露 问题排查

文章插图
 
选择对应的版本,下载后直接解压;默认情况下,mat 最大内存是 1024m ,而我们的 dump 文件往往大于 1024m,所以我们需要调整,在 mat 的 home 目录下找到 MemoryAnalyzer.ini ,将 -Xmx1024m 修改成大于 dump 大小的空间,我把它改成了 -Xmx4096m


推荐阅读