mybatis粗心使用导致内存溢出

文章描述了一个基础业务服务因内存溢出导致响应变慢的问题。通过分析GC日志和线程堆转储文件,发现是由于一次查询大量数据(几十万条)且由于方法重用,未传入的departmentIdList参数导致。解决方案是创建新的方法并增加条件限制,避免在departmentIdList为null时查询全部数据。
摘要由CSDN通过智能技术生成

现象

服务响应变慢,线程日志也出现Java heap space内存溢出的错误,这个服务属于基础业务服务,出现问题要尽快的排查

分析

因为设置了gc日志和jmap启动相关参数

所以我们进行分析,这里模拟线上环境将堆大小参数调整到了128m,完成的参数

-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms64M -Xmx64M -Xloggc:./gc.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+HeapDumpOnOutOfMemoryError

下面来分析这两个文件

gc.log

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以很明显的看出gc已经不能把对象进行回收了发生了内存泄露

hprof文件

在这里插入图片描述
从这张图能看到tomcat的一个线程里面的逻辑是从mysql查询数据,其中有个数据库字段类型为text占用空间比较大,映射的对象由于是String类型所以显示的是byte[]数组占用为2000byte。这个数组在这个集合内还有很多很多…

这肯定是不正常的现象,然后我们从日志调用链路查到了具体的接口,看到了mybatis中这条sql的逻辑
在这里插入图片描述
问题在departmentIdList参数,通过日志我们看到这个参数其实是没有传进来的为null,所以if条件是不进入的,这就导致把没必要的数据也全都查了出来,一次性查出了几十万的数据,再由于qps比较高,一下子就内存溢出了。

后来和开发人员沟通发现这个方法是之前就存在的,他是在原有的基础上添加了此条件,而别的地方也会用到这个方法不会带有这个参数,所以就查出了很多数据造成内存溢出。

解决思路

首先让开发人员另外写一个方法不要复用之前的,而且额外再加上条件限制。
在这里插入图片描述
这里加上了额外的条件限制,如果departmentIdList参数为null的话,则查询不到数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值