工作纪实40-内存飙高(线上问题大乱斗)

真是经历过一个项目从0-1,各种妖魔鬼怪都能遇见,尤其是qps还不低的情况下
前两天先后处理了cpu飙高的问题后,后来又有一个同事做数据同步(洗数据),一洗服务慢接口率就飙升,除了cpu使用率升了一点以外,内存使用率居然也上去了,而且非常明显;

内存不够用的场景我其实遇见过好几个,除了常规的堆栈文件分析以外,有几个问题小伙伴们可以优先关注:

  • docker模式下,可以观察一下宿主机的内存够不够(别老板的配置还没jvm启动的配置高)
  • 如果是CMS的垃圾回收器,宿主机的内存基本够用的情况下,观察一下jvm参数:-XX:CMSInitiatingOccupancyFraction,之前测试环境有个老六给他改成30%,死活起不来或者启动一段时间后自动崩
  • 其他情况,mat分析吧

可惜没有留下截图;但是问题的性质和特征还是很明显的,让运维导出了一下hprof文件;

下载mat内存分析工具:https://eclipse.dev/mat/downloads.php

就这居然还能遇见坑,我打开之后报错:
在这里插入图片描述
大致意思就是下面的这句话,重新让运维导出了一下
在这里插入图片描述
结果又发现我的mat一直卡死,打开的是个2g的hrpof堆栈文件;怀疑是分配的内存不够用
在这里插入图片描述
果断调到2个G,打开就丝滑了!

问题定位
进去先看Histogram
在这里插入图片描述
Histogram 列出每个类所对应的对象个数,以及所占用的内存大小(主要是它);
Leak Suspects:通过MAT自动分析当前内存泄露的主要原因
关注这两个菜单即可;
为了方便,我把分析的数据让mat使用智能模式,看起来更直观
在这里插入图片描述
点开Histogram
在这里插入图片描述
我解释一下这三列的意义:
Objects:实例对象的数量
Shallow Heap:实例对象占用的内存大小(仅单纯的将每个实例的大小相加汇总)
Retained Heap:实例对象若都可以被回收,那么可以被GC释放的内存大小(不仅需要考虑每个实例本身的大小,也会计算实例成员属性指向的实例的大小)

根据这个图,我大致怀疑是洗数据过程中,存在大量的查询db操作和new对象的操作【ResultSet和洗数据的那个类,很明显内存对象数是很靠前的,其他的基础String和List那些,大概率都是衍生创建的对象】

最终解决策略:
临时策略:单独申请一台内存足够大的机器(无入口流量),处理洗数据任务(一般的云平台都有这种扩缩容或者切流量的策略);
后续策略:优化洗数据逻辑,比如控制洗数据的批量处理数或者使用多线程;

一般来讲dump文件都很大,所以如果一时半会下载不下来的话,可以先试用jmap -histo:live命令,查看当前的类占用内存信息:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值