ThreadLocal导致的内存泄露

1.MAT分析

第一时间获取内存快照,使用MAT工具进行分析


MAT分析

发现有个120M的大对象

溢出位置

对这个大对象进行分析发现,内存溢出位置发生于ThreadLocal,里面存了一个Map,对应的值都是SessionInMemory

2.查找对应代码

发现该对象的位置是位于shiro-redis插件,找到该对象的使用位置发现


shiro-redis插件源码

shiro-redis插件源码

这里不断的put数据进去,导致内存溢出

3.原因

由于tomcat存在线程池,然后该插件作者为了提高性能,使用了ThreadLocal,然后维护的是一个Map对象,然而这个线程不会销毁,所以ThreadLocal一直存在,GC也无法使其回收

4.解决

更换shiro-redis的版本,从2.8.24升级到3.2.3


更换版本

新版本的修复


修复

作者添加了一行移除SessionInMemory的操作

5.监控

监控

5个小时内存几乎没有变化


JVM

产生了373次YGC,年老代占用11.15%

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。