最近一个服务频繁的进行full gc,而且几台同时gc,且不释放内存,怀疑内存泄漏了。于是,决定花时间好好整理解决一下这个问题。
方案如下:
1、加全局(redis)cache,缓存历史结果,减少实际逻辑执行次数;
2、找出“元凶”
以下针对第二点进行说明。
一、获取dump
命令:jcmp [pid] GC.heap_dump
坑:
With the 1.8 release, jstack and jmap (and probably others) have been removed from some java distributions (i.e. the windows distribution still has them, but they are not present on linux distributions).
所以,不能使用jmap了,只好用上面的迂回方法获取dump文件。
二、分析dump
使用工具:mat, 关键参数:MemoryAnalyzer.ini里面的-Xmx参数可以根据dump文件适当调整。
1、首先是load并且分析dump
2、获取dominator tree
3、找出“元凶”:HIDDEN_SYMBOLS_MAP
4、查看代码调用
总结
1、java8采用jcmd可以完成很多jmap之前完成的工作
2、mat工具直方图,dominator tree这些是分析内存泄漏的好工具
3、代码要注意,mutable的静态变量,一定要注意是内存泄漏的“元凶”
4、最关键的还是业务层要熟悉