一次OOM排查的详细经过

1.问题定位

预发环境机器出现访问502的问题。

登录机器查看日志,没有发现特别的日志。

考虑到QA刚刚在做压测,想到是不是出现了OOM问题。搜索错误日志:

cat error.log | grep "OutOf" 

果然有OOM错误日志:

java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: GC overhead limit exceeded

锁定是出现OOM问题。
这个错误的含义是每次垃圾回收能回收的内存占比极小。

2.查看PID

使用命令

jps -lvm

列出当前机器所有运行中的JVM进程。找到Web服务对应的进程,拿到你进程ID。

3.查看堆信息

jmpa -heap 1207

在这里插入图片描述
可以看到整个堆的最大值为1G,MaxHeapSize 1024M。其中老年代683,年轻代340。整体配置偏小,接下来就是确定是由于配置的内存偏小,导致的OOM,还是有其他内存泄漏导致的。

4.查看是哪些对象占用了内存

使用jmap -histo PID命令查看堆中对象的占比。

jmap -histo 1207

因为对象种类一般来说较多,可以将上述命令的输出存入文件,方便后续查看。

jmap -histo 1207 > obj.txt

之后可以使用less等命令查看:

less obj.txt

在这里插入图片描述
输出结果中instances表示对象个数,bytes表示占用内存的字节数。其中最多的是[C,这个[表示的数组的意思。C表示char,合起来就是字符数组char[],字符串String底层使用字符数组存储,这个一般说明有大量的字符串。不过这也说明不了啥,一般项目都是字符串较多。

另外看到数量较多有HashMap的Node节点。这个自然就是HashMap,这个需要查一下看是哪块逻辑在用。项目用了Caffine缓存看了底层是ConcurrentHashMap存储的,不知道这么多HashMap是做什么的?
有3万多个HashMap不知道是干啥的?

5.使用MAT进行一步分析堆转储文件

上一步使用jmap -histo查看了对象占用情况,要想进一步分析还需要生成堆转储文件。
使用命令:

jmap -dump:live,format=b,file=dump.bin 1207

生成堆转储文件,其中1207为版本号,file=dump.bin为存储文件路径,live选项表示进行一次GC只转化还存活的对象。

生成了堆转储文件,但是只能看到对象的数量和占用空间大小。对于HashMap、String等Java对象并不知道具体和什么业务相关。为了进一步分析还需要使用MAT。

https://blog.csdn.net/weixin_39850150/article/details/111250003
MAT使用的问题:
1.最新版本需要使用Java11以上。可以下载旧版本使用。
2.报错Failed to create the Java Virtual Machine。增加制定JVM目录的配置。https://blog.wintewu.com/archives/fix-mac-mat-start-failed-to-create-the-java-virtual-machine
配置文件:
/Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini
要增加的配置:
-vm
/Library/Java/JavaVirtualMachines/jdk-11.0.13.jdk/Contents/Home/bin

3.查看mac安装的jvm位置:
/usr/libexec/java_home -V

没有MAT时,也可以用jhat进行分析。
jhat为java自动的堆转储文件分析工具,特点是使用简单,不需要额外安装。
使用如下命令启动jhat

jhat dump.bin

其中dump.bin为堆转储文件。之后会启动一个http服务来查看分析结果,访问localhost:7000来进行查看。
默认进来展示了所有非Java原生类的情况,页面拉到最下面还有其他的页面可以查看:
在这里插入图片描述

6.分析结果

分析发现没有内存泄漏,单纯是内存设置过小导致的OOM。使用-Xmx6g 设置最大堆内存为6g,使用-Xms6g设置堆最小内存为6g,即进程启动后直接申请6g的内存使用。使用-Xmn2g设置年轻代大小为2g。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值