在Java中,OOME的问题时常碰到,这里整理了一次典型的OOME,总结定位的方法和步骤。
?
现象,heap size 4G , 10小时左右,总会OOME。
方法,尝试调高内存到6G, 13小时左右,还是OOME。
?
怀疑有内存泄露。
?
如何确认是内存泄露呢?
?
这里,我用的是HPjmeter.
?
1. 在JVM参数中加入如下参数
?
?
-verbose:gc -XX:+PrintGCDetails -Xloggc:./gc-host-$dateStr.log
?
注意,由于gc的log 在重启之后会被覆盖,最好每次创建一个新的文件,可以以时间作为区分。这里,dateStr=$(date +"%s")
?
2. 用HPjmeter 分析gc 。
?
?HPjmeter是一个gc的图形化分析工具,可以轻松地查看内存的回收状况,从而确认是否存在内存泄露。
这里,出现了这样的图
?
?
?
?
很显然,gc始终无法回收heap 资源。heap 使用量持续升高,明显有内存泄露。
?
?
怎么定位内存泄露?
?
?
1. 调小堆内存。 这里由 4G -> 1G .
2. JVM 加入如下参数。
?
-XX:+HeapDumpOnOutOfMemoryError
?
3. 重新跑
?
4. 程序重现了OOME, 并产生了 类似这样一个dump 文件。java_pid1666.hprof
?
5. 用mat 分析这个dump文件。
?
怎么用MAT分析dump文件?
?
具体的方法可以参考?http://qa.taobao.com/?p=14264
?
提一点就是linux下面使用Stand-alone Eclipse RCP Applications ,生成分析结果,然后再打包会window eclipse下面分析是一种比较方便的方法,尤其适合于大heap size的情况。
?
?
?
Note:
?
1. 在线上跑的时候,最好把上面提到的JVM参数都写上,减少定位问题的时间。
2. OOME未必就是内存泄露,有可能真是内存不够,这个可以通过HPjmeter来分析。
?
?
?
?
?
?
?
?
?
?
?