记一次内存泄漏排查

记一次内存泄漏排查

背景

最近某项目的服务突然告警,cpu超85%,随后就是服务宕机。交付重启服务后恢复正常但是随后不久又开始告警,特别是白天,严重影响客户业务进行。

问题排查

1、分析日志
查看日志的过程中发现存在内存溢出(OOM),思考要么存在内存泄漏要么业务上触发了某个接口存在大对象,结合业务情况,应该是前一种情况大一些。
在这里插入图片描述

2、查看CPU占用高的线程
按步骤

  1. top 找到cpu高的进程
  2. top -Hp pid 找到进程中cpu占的比较高的线程
  3. printf ‘%x’ 线程id 打印出线程16进制id
  4. jstack pid >xxx.txt 将线程信息输出到某个文件方便查询
  5. 将cpu高的那个在步骤4中的xxx.txt中搜索出来

排查出线程都是: gc task thread parallelgc 这类线程(忘记截图了)占用CPU高。那么这里其实可以大致得出结论了。

3、用arthas dashboard 查看应用运行情况
老年代占比98%,随后CPU飙升(很多公司生产可能都不允许使用arthas,上面步骤2其实基本可以得出结论了)

4、结论
代码存在内存泄漏,老年代占用率过高,导致系统频繁full gc ,从而系统CPU飙升直至宕机。

问题处理

1、给启动参数加上 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${目录} (这块疏忽,之前没加)
2、使用 MAT 分析 hprof文件

这里有个插曲,hprof文件太大,导致MAT打开报OOM。如果你是eclipse中安装的MAT 插件,可以在 setting(perferences)-> java -> Installed JREs -> jre -> edit -> variables 设置 内存大小 :
server -Xms4096m -Xmx4096m -XX:PermSize=512m -XX:MaxPermSize=512m
在这里插入图片描述

3、找到内存泄漏代码
有MAT帮忙,找到对应泄漏代码其实就简单多了。找到内存占用最大得结果线程进行查看就能看到对应的代码。

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

4、修改代码
看了下,是代码查询的时候,一次查询list过大导致的。后续和相关开发沟通后,优化了sql,重新发包部署。

5、观察
一段时间后服务器cpu恢复平稳~~~~~
在这里插入图片描述

至此,本次排查结束,服务CPU恢复正常状态。后面又了解,为啥之前服务运行的好好的,最近这么频繁宕机,一个是内存泄漏,还有就是业务方系统全面铺开,业务压力骤增,从原来的日均五万的量增加到了十万,后续可能还会增加,借此机会和业务方沟通,又升级了服务硬件配置,嘻~~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值