Hibernate QueryPlanCache引发的JVM内存泄漏

Hibernate QueryPlanCache引发的JVM内存泄漏

一、生产环境问题现象

一个经手多人的项目,项目中用到了hibernate作为ORM框架。生产环境中会出现HeapUsage持续缓慢上升的情况,导致触发HeapUsage超过80%的告警(见图1)。
图1. JVM Heap Usage监控

二、问题分析

生产环境dump内存快照(jmap -dump:live,format=b,file=/tmp/dump.hprof $pid)。通过MAT工具进行分析,发现char[]类型数据占比达61.1%(见图2)。List objects char[]类型数据,发现存在很多SQL字符串(见图3),对基本相同的两条SQL字符串进行文字对比,发现只有参数不同(见图4);同时SQL字符串被Hibernate的queryPlanCache持有(见图5)。

至此,可以判断是SQL缓存导致的问题。Google后发现应该是代码中拼接的SQL每次执行时参数不同导致Hibernate重复缓存SQL。全文检索代码,确实找到了问题(见图7)。

图2. MAT Histogram
图3. SQL语句
图4. 文本对比
图5. Path To GC Roots
图6. 问题代码

三、解决方案

两方面入手:配置+代码

  1. 修改Hibernate配置
    线上稳定第一位,首先修改Hibernate配置,确保生产环境稳定。可以通过修改下面配置实现:
spring:
  jpa:
    properties:
      hibernate:
        query:
		  #controls the maximum number of entries in the plan cache (defaults to 2048)
          plan_cache_max_size: 64
#manages the number of ParameterMetadata instances in the cache (defaults to 128)
          plan_parameter_metadata_max_size: 32
#Sets the maximum number of strong references held in the cache. e.g. 128 (default)
          plan_cache_max_soft_references: 1024
#Sets the maximum number of soft references held in the cache. Set this value to Integer.MAX_VALUE to replicate the behavior of 5.1.1 and earlier. e.g. 2048 (default)
          plan_cache_max_strong_references: 64

  1. 修改问题代码
    后续更新。。。。。。

四、测试环境验证

进行中,后续更新。。。。。。

五、生产上线

后续更新。。。。。。

六、总结

后续更新。。。。。。
项目中不止这一个问题,还需要一个一个解决

  1. 缓存应该用WeakReference或SoftReference
  2. 分布式系统资源配额

七、参考

  1. Hibernate文档
  2. https://access.redhat.com/documentation/en-us/jboss_enterprise_application_platform/5/html/hibernate_core_reference_guide/configuration-optional
  3. https://www.codenong.com/31557076/
  4. https://www.thinbug.com/q/31557076
  5. https://blog.csdn.net/qq_38425719/article/details/103856377
  6. https://blog.csdn.net/dream_lixiang/article/details/77248292
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值