1.MAT分析
第一時(shí)間獲取內(nèi)存快照,使用MAT工具進(jìn)行分析

MAT分析
發(fā)現(xiàn)有個(gè)120M的大對(duì)象

溢出位置
對(duì)這個(gè)大對(duì)象進(jìn)行分析發(fā)現(xiàn),內(nèi)存溢出位置發(fā)生于ThreadLocal,里面存了一個(gè)Map,對(duì)應(yīng)的值都是
SessionInMemory
2.查找對(duì)應(yīng)代碼
發(fā)現(xiàn)該對(duì)象的位置是位于shiro-redis插件,找到該對(duì)象的使用位置發(fā)現(xiàn)

shiro-redis插件源碼

shiro-redis插件源碼
這里不斷的put數(shù)據(jù)進(jìn)去,導(dǎo)致內(nèi)存溢出
3.原因
由于tomcat存在線程池,然后該插件作者為了提高性能,使用了ThreadLocal,然后維護(hù)的是一個(gè)Map對(duì)象,然而這個(gè)線程不會(huì)銷毀,所以ThreadLocal一直存在,GC也無法使其回收
4.解決
更換shiro-redis的版本,從2.8.24升級(jí)到3.2.3

更換版本
新版本的修復(fù)

修復(fù)
作者添加了一行移除SessionInMemory的操作
5.監(jiān)控

監(jiān)控
5個(gè)小時(shí)內(nèi)存幾乎沒有變化

JVM
產(chǎn)生了373次YGC,年老代占用11.15%