Druid版本
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.16</version>
</dependency>
现象 😣
早上起来看到告警群中全部都是项目的FullGC告警,其中还夹杂着部分OOM的告警. 甚至还有2台Tomcat没有上线也存在这个情况.
说明不是外部请求导致的. 且该项目后台启动了一个线程用于消费消息队列.
处理问题 🌲
看实例对象
看堆栈
使用
对 jstack
生成对堆栈进行分析,一无所获. 处于 Runnable
中的线程寥寥无几.. 根据不包含这个数据
dump 😂
命令 jmap -dump:live,format=b,file=pid.hprof pid
使用 mat
打开dump文件,可以直观的看到
看是否是瞬时流量导致OOM,操作Incoming
和 Outcoming
,没有找到,确定是内存泄露导致的内存溢出。
2020-12-28补充 这里我陷入了一个误区(或者是一个长久以来错误的认知), 我错误的认为这个是在查询的过程中撑爆了内存(这个有可能,但是我以为大部分是这样,就犯错了)。 其实内存泄漏是一个缓慢进行的过程,并不是一蹴而就的. 所以只要找到最大的堆积即可,不要太固执的去找所谓的堆栈…
换成 JProfiler
试试 (刚下载把玩,感觉和mat差不多,界面美观不少)
打开dump下来对hprof文件. 和MAT显示的差不多. com.alibaba.druid.stata.JdbcDataSourceStat$1
这个竟然包含了这么多,有经验的开发者都知道 $1
是类内部的一个实例类. 举个例子.
源文件
编译后的class文件…
打开 idea
开始看这个类.
在看是在哪里 put
数据的
到这里基本上就明白了,是因为配置 DataSource
的时候 Filter
配置了 stat
参数. 快速去掉发布上线.
第二天一看,稳的一批..
总结
看这个dump文件是比较难受,尤其是我的思考方向错误的时候. 很想知道根据这个对象来找到它的堆栈入口,各种点,结果根本就没有,这里还是思考🤔方向错误了. 下次就不会如此了.
这个Filter是用于界面看数据使用的,如果我们不看或者是有其他途径看sql,其实是可以关闭的.
思考
在什么情况下 sqlStatMap
会把数据给清空呢? 当时又是源于什么情况导致Map堆积了这么多的数据呢?