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

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

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

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

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

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

就这居然还能遇见坑,我打开之后报错:
工作纪实40-内存飙高(线上问题大乱斗)_第1张图片
大致意思就是下面的这句话,重新让运维导出了一下
在这里插入图片描述
结果又发现我的mat一直卡死,打开的是个2g的hrpof堆栈文件;怀疑是分配的内存不够用
工作纪实40-内存飙高(线上问题大乱斗)_第2张图片
果断调到2个G,打开就丝滑了!

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

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

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

你可能感兴趣的:(工作纪实,java)