一次JPA 内存泄露问题排查

机器:2C4G

程序:用户同步程序

现象:2023.9.15~2023.9.18之间,只要启动全量同步,10分钟内就会发生内存泄漏


排查:

1.代码查看。经查看,代码有Map引用,用于数据比较,使用后并清除,正常

2.线程排查。经查看,线程只启动了3个同步线程,线程正常范围

3.使用jmap 查看内存分布

  • jmap -histo:live 16372 > 16372.txt
  • 主要对象是hashMap\$Node和org.hibernate.hql.internal.ast.tree.Node

uploaded!

4.使用jmap把内存dump下来分析

  • jmap -dump:format=b,file=/tmp/memory_dump.hprof 16372
  • 可以看出来主要对象是org.hibernate.internal.SessionFactoryImpl,占用已超2G
    • org.hibernate.engine.query.spi.QueryPlanCache

uploaded!

5.分析

  • 从内存分布和内存快照来看,基本上可以确定,溢出原因就是org.hibernate.internal.SessionFactoryImpl这个类中的org.hibernate.engine.query.spi.QueryPlanCache导致

  • 查阅相关文档, hibernate有缓存机制,主要是QueryPlanCache。查询执行过程中会先去queryPlanCache中获取,如果没有才会去查询库,然后查询和结果值放queryPlanCache中。

  • 在queryPlanCache中由org.hibernate.internal.util.collections.BoundedConcurrentHashMap实现,capacity默认为2048,也就是缓存最大查询计划数为2048,那只需要把capacity这个缓存查询数变小即可

uploaded!


6.修复和运行查看

  • 把程序配置上加上以下配置后再运行

    • spring.jpa.properties.hibernate.query.plan_cache_max_size=512
    • spring.jpa.properties.hibernate.query.plan_parameter_metadata_max_size=32
  • 结果如下图,也无内存溢出

uploaded!

overwrote existing file

本文地址 https://www.frank8g2g3.cn/2023/12/13/一次JPA-内存泄露问题排查/

frank wechat
扫描二唯码,订阅我的公众号