MAT分析线上OOM实例

一问题

群里小伙伴说发生oom了。我没有那台机器权限,先保留现场,找人生成dump文件(jmap -dump:format=b,file=heapDump  XXXX)是对应的进程id。然后重启。当然生成文件较大,2.4G 需要一段时间,会造成一次FullGC。非紧急时刻业务高峰期慎用。

  当然更推荐一种在启动脚本就加上配置:-XX:+HeapDumpOnOutOfMemoryError 这样发生OOM就不用再手动生成了。

  紧急排查问题,jmap -histo:live 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀

看下前10的也大概能有助于锁定范围。比如这个就是一个自定义的业务bean entity很多,74W条。

二 mat 分析

mat 还是很强大的。

打开文件后,提示错误。

这个不是文件不完整,是我本地电脑内存不够了,因为mat默认的是1024M.这个文件就2G多了,还要分析,所以改为-Xmx3072m 就ok了。

总体视图:

2G内存,这个jdbc的结果集就占了1.4G,70%的占用,因此强烈关注与此。

2 histogram: 这个一开始看class的实例数目,内存占用差不多,内容更详细,objects是数量,shallow heap 是本身占用大小,retained heap是实际加上引用占用大小。

看这个基本上就能找方向,结果集及对应的entity可能有问题。

继续看占用最大的结果集是啥?

dominator:List the biggest objects and what they keep alive.

知道对应的结果集内容,跟entity想匹配。单条数据在1.5K左右。

看完这些总体的,改看下具体的原因。mat会给出可疑的分析:

这里就是发生oom对应的线程,看线程的详细信息:

内部RPC框架,可以一层层的看到调用关系,其中dao层可以看到SQL。

select * from table where user_id=?

这里有个插曲,没看到sql之前,我就猜想应该根据条件查询没有limit导致的。

但是这个sql有条件,我强烈怀疑某个id有大量的数据几W那种。

工程是别人的,业务也不懂,小伙伴说没有多条,都是一对一的。

被否定了,可是这100多W条的restset怎么来的呢?难道是一直反复查询不释放。

在找人看看发生oom的日志,上下文无有效信息。

没招了,看阿里云的数据库监控吧,看看有没有慢sql或者之前的那种jdbc连接数过多那种。

真的有,时间点与sql匹配的上,参数是0.执行了1g秒却没有提示慢SQL,返回是1.7m就是170W,跟结果集的169W对应。

问下业务的同学,原来0是特殊情况,历史的数据100多W这种默认为0 的。

至此,确认无疑。因为是偶发的调用,所以问题出现频率不高,但是一旦查询返回结果集过大,则会爆掉。

三 改进

要了对应工程git权限,看下这块代码。

也是祖传代码,维护的同学表示无辜。看下逻辑,还是取一条。

那就改下SQL 加上limit 1吧。

反思:对于帮忙排查问题,面临的是机器,代码都不熟悉的情况,需要对应的业务同学帮忙确认问题,但是又不能全信。因为他说的是正常的业务流程,对于极端的异常情况是没有考虑到的。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值