记一次OOM问题排查过程

这周生产环境出了久违的java.lang.OutOfMemoryError: Java heap space,花了些时间找了下缘由,记录分享一下 🥕java

OOM分析

以前的jvm优化的文章中,有提到要增长-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/logs/login/gc,这对于排查问题很是有帮助,当发生OOM时就会输出堆的内存快照(hprof文件)。git

从生产环境拷贝出hprof文件后,就能够用MAT或者Jvisualvm来分析了,相对来讲MAT更智能和易用一些。github

用MAT打开hprof文件后,很明显能够看到(这里补充一个小插曲:在jdk11的环境下,MAT会报错没法打开,建议切回jdk8的环境打开MAT)spring

经过Leak Suspects其实已经能够看出问题所在了,SessionFactoryImpl这个实例占用了87.48%的内存。很明显是内存泄漏了。sql

MAT-1

咱们打开Histogram,能够看到类的实例数和所占的内存缓存

MAT-1

这个看起来还并非很清晰,能够排除软,弱,虚引用(剩下强引用)看的更加直观bash

MAT-1

如今就很明显了,SessionFactoryImpl中的QueryPlanCache形成了内存泄漏jvm

MAT-1

QueryPlanCache内存泄漏解决

那什么是QueryPlanCache呢,hibernate中的QueryPlanCache会缓存sql,以便于后边的相同的sql重复编译。优化

若是in后的参数不一样,hibernate会把其当成不一样的sql进行缓存,从而缓存大量的sql致使heap内存溢出。spa

因此能够经过设置缓存最大值来进行限制,不设置默认是2G。

spring:
  jpa:
    properties:
      hibernate:
        query:
          plan_cache_max_size: 64
          plan_parameter_metadata_max_size: 32
复制代码

Github 不要吝啬你的star ^.^
更多精彩 戳我

相关文章
相关标签/搜索