mybatis的guava内存溢出

1 背景

以sc-pacific-qi-service OOM作为分析案例

问题现象:set-gh-service-kaeru-csc-pacific-qi-service02 cpu load及频繁fullgc告警。

分析思路:先去raptor查看当前机器的使用情况,cpu load,对cms,jvm内存情况。

2 Raptor分析

2.1 观察gc次数

如下图左侧,fullgccount很稳定,每分钟发生7-8次,曲线非常均匀。根据这个图基本可以确认内存泄漏了,而且每次回收一点也没有回收掉。但是哪个区域泄漏,还需要其他的数据分析
在这里插入图片描述

2.2 观察jvm内存区域的gc情况

eden区域曲线很均匀,metaspace区域很稳定,在安全范围,所以可以排除元数据区域oom。

oldgen的区域内存一致持续不变,而另外一台机器的内存是持续在增长,结合上面的gc在频繁发生,可以分析,产生了old区发生了内存泄漏
在这里插入图片描述

2.3 MAT分析

2.3.1 MAT官方文档

https://help.eclipse.org/2021-06/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html

2.3.2 Getting Started Wizard

2.3.2.1 Leak Suspects 内存泄露报表

自动检查可能存在内存泄露的对象,通过报表展示存活的对象以及为什么他们没有被垃圾收集;
在这里插入图片描述

2.3.2.2 Component Report对象报表

对可疑对象的分析,如字符串是否定义重了,空的collection、finalizer以及弱引用等

2.3.3 OverView

打开一个dump文件后一般会先选择leak suspect界面。overview界面会以饼图的方式显示当前消耗内存最多的几类对象,可以使我们对当前内存消耗有一个直观的印象。但是,除非你的程序内存泄漏特别明显或者你正好在生成hprof文件之前复现了程序的内存泄漏场景,你才可能通过这个界面猜到程序出问题的地方,一句话就是比较看运气。

查看下图很直观,DefaultSqlSessionFactory很可能发生了内存泄漏

2.3.4 Histogram

2.3.4.1 shallow heap

指的是某一个对象所占内存大小。

2.3.4.2 retained heap

指的是一个对象的retained set所包含对象所占内存的总大小。

retained set指的是这个对象本身和他持有引用的对象和这些对象的retained set所占内存大小的总和,用官方的一张图来解释如下:
在这里插入图片描述

Lists number of instances per class

查看下图,Long的对象有1099w个,占用263M空间

Char数组对象有29w个,占用961M
在这里插入图片描述

2.3.5 Dominator Tree

List the biggest objects and what they keep alive.
在这里插入图片描述

基本可以定位是DefaultSqlSessionFactory下的PageInterceptor下的GuavaCache出了问题

2.3.6 实操分析

①先定位GuavaCache,然后找到对应的put代码的引用
在这里插入图片描述

②找到实际缓存的容器msCountMap
在这里插入图片描述

②结合mat的分析结果,找到map的key和value与目标完全一致,基本定位是msCountMap.put这块代码有问题
在这里插入图片描述

问题原因是因为统计代码的Sql太大,每条sql有7.4M,总共有170 * 7.4M = 1.2G,与问题现象一致。可以定位是该位置问题导致

③深入分析每条缓存为什么占用这么大的空间

是因为CacheKey比较大,具体就是其属性sql比较大,sql大是因为参数多,总共有7.1w个参数
在这里插入图片描述

④查看CacheKey的数据结构,注意查看updateList
在这里插入图片描述

⑤查看CacheKey创建过程

在这里插入图片描述

⑥查看实际测试结果
在这里插入图片描述

2.3.7 问题原因

在分页查询的时候,会缓存执行总条数,因为使用了CacheKey做Key,所以对于不同的SQL,如sql参数数量、顺序等等,都不会命中,而且是永久性缓存,所以导致内存被占用无法回收

2.4 解决方法

2.4.1 根本原因

guava默认缓存1000条数据,假如没有配置过期时间,则永不过期,这点和GC后内存占用是一致的。
在这里插入图片描述

2.4.2 修复方法

增加缓存最大数量限制,问题解决
在这里插入图片描述

样例:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值