线上OOM异常案例及排查过程

线上OOM异常案例及排查过程

1.导出堆转储文件分析

由于 启动脚本里面加了 -XX:HeapDumpPath=./gcLog/java_%p_%t.hprof -XX:+HeapDumpOnOutOfMemoryE
rror ,所以 发生OOM异常的时候 会自动生成 堆转储文件放到配置的指定位置。启动脚本如下:
在这里插入图片描述
从服务器 把 堆转储文件 down下来之后 ,用jvisualvm来分析dump文件。

 	jvisualvm是JDK自带的Java性能分析工具,在JDK的bin目录下,文件名就叫jvisualvm.exe。
 	
	 jvisualvm可以监控本地、远程的java进程,实时查看进程的cpu、堆、线程等参数,对java进程生成dump文件,并对dump文件进行分析。像我这种从服务器上dump下来文件也可以直接扔给jvisualvm来分析。

	使用方式:直接双击打开jvisualvm.exe,点击文件->装入,在文件类型那一栏选择堆,选择要分析的dump文件,打开。	

在这里插入图片描述

在这里插入图片描述

用JVisualVM打开文件后就会看到提示这里有异常,点击进入这个线程异常,就可以看到报错信息
在这里插入图片描述

在这里插入图片描述
dd

根据上面的报错信息 我们 可以定位到 程序代码的具体位置。CoreWxNoticeServiceImpl.java 文件的38 行,WxNoticeQuery.java 的 45 行。

在这里插入图片描述
在这里插入图片描述

看到这里,刚开始怀疑是不是查询出来的数据太多,导致往list 放的太多 造成OOM了。
BUT… 拿到对应的sql脚本 执行时,发现查询的出来的数据并不多,只有6百多条。
怪哉。。。。。
只能去分析对象实例了。。。。
在这里插入图片描述

找到真正的问题所在:

后来 ,通过查看阿里云的sql执行管理 平台,发现 服务器异常的 那个时间点,有一条sql 执行查出来了 六十多万用户数据。
找到程序的那个地方,原来那个 sql 查询 传入的是一个map ,而 map 中的值有没有 判断 空(实际业务中那里不应该为空的,为空时应该直接返回 入参为空的异常),导致查出了所有的用户数据。共60多万条,有480多M 数据(总的堆内存是1G)。

分析:
应该是这里 查询的数据太多,占了太多内存,快要接近临界值了,后面又 接着 处理其他的逻辑 ,查其他数据时(CoreWxNoticeServiceImpl.java 文件的38 行),虽然其他的数据 不多,但是 总的占用 就溢出了,所以看到报错的地方 是 CoreWxNoticeServiceImpl.java 文件的38 行 这里。

解决办法:
在执行查询用户的那个sql 之前 加 一个 判断,如果 map 里面的参数 同时为空 ,则 不往下走,直接返回 参数为空的异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值