java.lang.OutOfMemoryError是工作中常见的异常,今天介绍下如何分析java内存泄漏。
java内存分析工具很多,JDK安装目录下自带就有很多优秀的分析工具。分析堆栈时我比较推荐使用MAT,方便,快速。
安装MAT
打开eclipse --->help--->eclipse marketplace(我在公司一般会下载高版本的eclipse,它带有一个插件应用市场,安装插件比较方便),输入mat搜索,看到如下图点击安装
安装完成后,使用使用jdk的jmap命令,在运行中的java程序生成Dump文件
jmap -dump:format=b,file=${文件路径} 进程ID
如果只dump heap中的存活对象,则加上选项-live
jmap -dump:live,format=b,file=${文件路径} 进程ID
使用mat打开dump文件
File -> Import -> Other -> Heap Dump 然后选择Dump文件的路径,选择文件进行导入
图中可以看到一个线程占了堆中90%多的内存。
从上图可以看到它提供的一些功能:
1) Histogram可以查看内存中的对象,对象的个数以及大小。
2.)Dominator Tree可以列出线程,以及线程下面的那些对象占用的空间。
3)Top consumers通过图形列出最大的object。
4)Leak Suspects通过MA自动分析泄漏的原因。
一般分析问题可以直接进入Leak Suspects查看内存泄漏点。
从 图可以看到mat自动分析出一个内存泄漏点
点开See stacktrace,可以看到线程运行的栈,点开Details 可以看到线程所引用的对象,对象所占内存大小。
当程序出现OOM时,结合应用程序代码和 stacktrace,Details 中占用内存大的对象可以快速定位到内存溢出的代码。
jvm参数加上: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/heap/dump,当jvm出现OOM时会自动生成dump文件,方便定位问题。
我们生产一个服务就出现过OOM,开始在外拓展简单处理将jvm内存加到几十G都,后面还是被撑爆 ,回来后通过mat分析dump文件堆栈很快定位问题并修复,修复后jvm内存稳定在500M左右,这次内存泄漏是由apache ftp jar包引起的,上传图片到ftp的一个目录,ftp工具类会加载遍历目录下所有图片进行匹配,所以时间久图片越来越多,就出现问题了。