年轻代频繁GC,大量FlushEntityEvent等hibernate对象(hibernate的内存泄漏)问题解决

现象

  • 高并发请求,需要操作数据库。大量的查询、删除、插入、更新操作。
  • 一次请求需要处理10万条数据左右,每条数据处理,都需要查询、删除、插入、更新多次,操作多张表。
  • 为了防止内存溢出,一次处理1000条。在Controller层方法分页,处理在service层执行,这样每处理1000条,提交一次。
  • 程序初始运行很快,处理1000个大概10秒,后来逐步的越来越慢,逐步变大,变成几十、几百、直至一千多秒
  • 年轻代GC频繁,但是没有STW,GC时间也不长,影响不大
  • 重启项目后,重新执行,还是这种情况。一开始很快,后来越来越慢

排查

  • arthas
  • jmap
    在这里插入图片描述

结果

  • 最终定位到hibernate内存泄漏
  • FlushEntityEvent向上追踪调用堆栈,是hibernate查询方法q.list()
  • session没有清空,越来越多,释放不了
  • 正常使用没问题,但是高并发的时候,来不及释放清空session,越用越慢
  • 清空后可以,每1000条,7秒左右,直到处理完20万左右数据,仍然是10秒左右的时间,符合业务需求
  • 清空session对其他操作数据库的方法执行有影响,只修改了本方法,处理一批次1000条后,清空一次。为了排除对其他业务的影响,为了这个数据处理方法,单独部署一个服务。
  • 在dao层添加方法,获取当前session,并清空,先flushclear
    public void clearSession() {
        Session session = this.getCurrentSession();
        session.flush();
        session.clear();
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坚持是一种态度

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值