加载页面数据时内存突然爆满_线上java内存泄露处理实录

270fc5f87c9c832bf0abba602f71472b.png

线上现象(各种监控数据)

1.公司项目在监控平台上开始报警(jvm堆内存占用报警,FullGC次数超频率报警)

ae48251e33235c02e4f765b319a252ca.png

2.观察具体的监控图标(预发机器) 线程数平稳(260左右)

199c2889a9d9ae35d1a847674859d2f3.png

e230e1a1ab8e283c8f5c3e5542df3c4e.png

a5194f41d40d74d97719a88e1a67f648.png

abf0ea19178286dc947cd1eda3aba0ac.png
  1. 方法监控可以看到在fullGC比较频繁时,业务方法几乎无响应

6c921310513dc5392463221edeecf578.png

线上配置(jvm配置,运行时内存分布)

  1. 项目版本:jdk8 ,spring 5, 默认垃圾处理器 Parallel GC with 43 thread(s) -Xms800m -Xmx800m -XX:MaxPermSize=256m

5bc9fce3f1adb13fbc251e2782d060d8.png
  1. 运行时jstat

2832025441b64670e62a610b5b575bb4.png
  1. 运行时jmap histo

a49ab025961af32346d50a48fc4744c8.png
  1. heap

8de9c7d5bbd81d372f5b3e0d580afe57.png

5.dump文件1G左右,不发了,稍后看一下MAT分析的图表吧

逻辑分析(定位问题大致方向)

  1. 通过监控和运行时数据分析,堆内存(年轻代和老年代)、非堆(方法区)、均打满配置内存
  2. 即使FullGC,堆内存和非堆也只能回收少许内存,并且整体水位倾斜向上,直到内存溢出

通过逻辑分析,内存溢出问题来自于存在泄漏,接下来分析dump文件

内存分析(定位问题确切泄漏源)

采用MAT工具载入dump文件进行leak分析

3ad3f5f7f8965e7b9fa09d486e88237b.png

d01e5cc46e37dad35eb5e52648c24bf4.png

通过分析可以看出红色的业务方法保留引用太多, 找到泄漏源了,接下来就分析业务代码具体的问题

d71ae55c47cd5a74771a7bc08069a200.png

a57e1331cecba7f503de5c61cfde96b5.png

通过分析,我们最终定位了这段代码,我们改造过程中引入了一个开源的属性运行时拷贝的包
但是我们每次转换的时候都会先register一遍转换代理类,而此类底层为每次register注册一个新生的代理类被加载到非堆
但是又被业务代码中的MAPPER_FACTORY引用,导致每次生成的实例充斥着年轻代又到老年代
最终的现象就是老年代、年轻代、非堆内存同时爆满,而又GC不掉,内存泄露直到溢出

代码处理

找到了具体的代码问题,我们将同一个类转换的register在系统启动时注入一次就行,不用每次调用注册,这样的话就不会频繁创建和加载,就可以解决上述问题

本地验证

本地验证错误使用代码,可以复现问题

1d00b6a2c629f9ea65d91311d635729b.png

7b112a959ae8115156911a30ddd03391.png

cf332052556871f2616c25c8ffc29ad8.png

加入 参数-verbose -verbose:gc 也 可以看到新增的代理类在循环中疯狂生成与加载, 修复后本地监控数据平稳运行,具体图标参考预发验证图表

预发验证

23d370086644534a640b3b02a1fab4a1.png

f4b974bd5ee114bd73bb7aa28e60f497.png

e2d34697f3b70f1fd259e1f080d3b491.png

a42f09ade39a4503435e043181c558c1.png

预发验证后续我们还将采用压测排除性能与其他内存问题,此次排除结束。

后记

此次问题还是属于比较常见的内存溢出分析,整体按着常用流程没有太多的难点,只有在分析register的时候一时定位不到是开源包的register方法调用的原因(虽然事后感觉很简单,当时也是耗费了30分钟左右才发现)。
troube shooting 三要素: 锻炼自己的逻辑思维、锻炼自己的技术能力、多看多查

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值