jvm 内存泄漏分析方法
1、首先通过 free -m \nmon 查看系统内存的使用情况。若出现内存使用率不断增高。且没有降低的趋势,则系统出现了内存泄漏。
2、再使用 top 命令查看是哪个进程耗的内存比较多。通过快捷键 shift+m 对内存进行排序。
3、若查看到 java 内存使用的内存比较多。则使用命令查看 fullgc 次数。
命令:jstat -gc 31260 5000 每五秒打印一次
4、执行命令打印堆栈信息 堆文件为 aaa.hprof
jmap -dump:live,format=b,file=aaa.hprof 18037
5、查看进程中类的数量
jmap -histo:live 18037
通过查看进程中类的数量推测程序那块持续的创建了大量的类,导致了内存泄漏。
6、或者使用 mat 分析工具对步骤 4 打印的 aaa.hprof 文件进行分析找到占用大量内存的线程。
7、MAT 使用方式
参考网址:https://blog.csdn.net/wanghuiqi2008/article/details/50724676
在 All Accumulated Objects by Class 列举了该对象所存储的所有内容。
为了找到内存泄露,我获取了两个堆转储文件,两个文件获取时间间隔是一天(因为内存只是小幅度增长,短时间很难发现问题)。对比两个文件的对象,通过对比后的结果可以很方便定位内存泄露。
MAT 同时打开两个堆转储文件,分别打开 Histogram,如下图。在下图中方框 1 按钮用于对比两个 Histogram,对比后在方框 2 处选择 Group By package,然后对比各对象的变化。不难发现 heap3.hprof 比 heap6.hprof 少了 64 个 eventInfo 对象,如果对代码比较熟悉的话想必这样一个结果是能够给程序员一定的启示的。而我也是根据这个启示差找到了最终内存泄露的位置。
我内存泄露位置是一个 list,这个 list 只在这里一直不停的往里添加 eventInfo 对象,却没有释放过。