Jvm FullGC、 Oom 以及CPU占用100%,如何排查?
使用场景
我们在使用系统时,有时请求和响应会变得特别慢,系统也变得很卡。
有可能是CPU占用100%,或者是 FullGC的问题,可以逐步地进行排查。
使用jps和top确定进程号pid
jps可以列出正在运行的jvm进程,并显示jvm执行主类名称( main()函数所在的类),以及进程id。
命令如下:
jps -l
结果如下:
一、Cpu 占用100% ,如何排查?
而top命令查看cpu使用情况,获取对应的进程号pid:
top
如下所示,发现进程号pid为72的进程占用了近100%的cpu:
如果想知道该进程是什么,可以使用以下命令查看:
ps -ef | grep 进程号
查看在这个进程中消耗cpu最多的线程
命令如下:
top -H -p 72
可以查看在72这个进程的各个线程
-H表示 Threads-mode operation,线程模式,展示各个线程。
-p表示 Monitor-PIDs mode,监控模式,通过进程id监控进程。
详情见: https://blog.csdn.net/qq_31302009/article/details/77803006
结果如下,可以看到消耗cpu最多的线程号80和79:
- 计算线程号的16进制结果
printf %x 79
将线程号80和79分别转换成16进制,将结果4f和50记下来,可以在后面的dump文件搜索。
jstack分析线程堆栈,并保存结果
- 根据进程号,输出进程的线程dump文件。
以下命令是将进程号为72的dump文件,输出到 /tmp/dump_file这个路径,也可以是其他任意路径。
> 表示将命令执行的结果保存到文件并覆盖原文件的内容。
jstack 72 > /tmp/dump_file
- 打开dump文件,根据之前printf %x计算得到的16进制结果搜索。
比如printf %x 79 计算得到的结果为4f,可以通过4f进行搜索,也可以用0x4f搜索。
(注:如果不想保存文件,也可以直接用命令
jstack -l 72 | grep 0x4f -C 10
jstack -l显示线程堆栈详情,grep匹配关键字0x4f,-C 10表示显示关键字前后10行。)
主要看nid。 nid,意思是 native thread id. 每一个nid对应于linux下的一个tid。
jstack中的nid是十六进制数。
搜索找到 nid=0x4f 的线程,就可以拿到线程的堆栈,找到出问题的代码了。
如果想找出有死锁的线程,也可以通过 BLOCKED 关键字去匹配。
jstack –l 72 | grep -i –E 'BLOCKED | deadlock'
二、Jvm 频繁 FullGC , Oom ,如何排查?
jstat检查进程号的gc,是否发生fullGC:
jstat,就是JVM Statistics Monitoring Tool.
下面这个命令的意思是每隔2s显示pid为72的进程的GC情况:
jstat -gcutil 72 2000
结果如下:
我们主要观察FGC这个参数,可以发现,每隔几秒,FGC的次数就会变多。
具体的含义如下:
参数含义:
S0 : Heap 上的 Survivor space 0 段已使用空间的百分比
S1 : Heap 上的 Survivor space 1 段已使用空间的百分比
E : Heap 上的 Eden space 段已使用空间的百分比
O : Heap 上的 Old space 段已使用空间的百分比
P : Perm space 已使用空间的百分比
YGC :从程序启动到采样时发生 Young GC 的次数
YGCT : Young GC 所用的时间 ( 单位秒 )
FGC :从程序启动到采样时发生 Full GC 的次数
FGCT : Full GC 所用的时间 ( 单位秒 )
GCT :用于垃圾回收的总时间 ( 单位秒 )
jmap分析进程的内存
jmap -histo 在实际使用中,用的并不多。可以直接看下文的 jmap dump 文件。
- jmap分析进程72的内存使用情况,并保存dump文件
jmap,就是Java Memory Map.
jmap -histo 72 > pid72.log
以上命令中的 pid72.log是文件名称,也可以改用其他名称。而72是进程号。
查到 pid72.log 文件,内存的使用情况如下:
参数的含义如下:
说明:
#instance 是对象的实例个数
#bytes 是总占用的字节数
class name 对应的就是 Class 文件里的 class 的标识
B 代表 byte
C 代表 char
D 代表 double
F 代表 float
I 代表 int
J 代表 long
Z 代表 boolean
前边有 [ 代表数组, [I 就相当于 int[]
对象用 [L+ 类名表示
jmap dump 文件 ,分析 fullGc、Oom
如果对象频繁 fullGc,或者是 oom , 那么可以使用 jmap 来 dump 文件分析 oom。
jmap -dump:format=b,file=/tmp/dump-a.hprof 进程号
或者是如下:
live子选项是可选的,假如指定live选项,那么只输出活的对象到文件:
jmap -dump:live,format=b,file=/tmp/dump-a.hprof 进程号
这个 dump 的命令非常有用。 分析 oom时经常会用到。
这个 dump 文件往往非常大,可以使用 bzip2 进行压缩,方便下载。
bzip2 -9 -k /tmp/dump-a.hprof
jhat分析jmap生成的堆内存快照
jhat ,在实际中用得并不多。可以直接看下文的 分析dump文件。
jhat,就是JVM Heap Analysis Tool,虚拟机堆内存快照分析工具。
jhat,可以用来分析jmap生成的堆内存文件。
除了jhat,也可以用专业用于分析dump文件的Memory Analyzer(MAT)等工具。
jmap -dump:format=b,file=a.hprof 72
jhat -J-Xmx512M a.hprof
a.hprof是文件名称,也可以改用其他命名。
结果如下:
屏幕显示"Server is ready."的提示后,用户在浏览器中输入http://要访问的ip:7000/,
比如 http://localhost:7000/ 就可以看到分析结果了。
分析结果默认是以包为单位进行分组显示,分析内存泄漏问题主要会使用到其中的 "Heap Histogram",可以找到内存中总量最大的对象。
分析dump文件
详情见:https://blog.csdn.net/sinat_32502451/article/details/137092200
参考资料
《深入理解java虚拟机》
https://blog.csdn.net/weixin_34320159/article/details/91553350
https://www.cnblogs.com/kongzhongqijing/articles/3621223.html
https://www.cnblogs.com/kingszelda/p/9034191.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2018-03-14 关于Url传递参数