现象

JAVA进程启动时设置了内存大小 -Xmx12000m -Xms12000m -Xmn8000m,运行过程中出现outofmemory错误,超过最大内存后,进程重启 。

排查

为了定位问题,在JVM启动参数里面开启自动dump的选项,JVM参数有几个选项可以进行自动dump:HeapDumpOnOutOfMemoryError, HeapDumpBeforeFullGC, HeapDumpAfterFullGC。由于错误码里面是OutOfMemoryError错误,

OOM的异常排查过程_内存泄露

因此在java进程启动参数里面加了-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/obs/gc.dump

 

定位

进程再次outofmemory后,在/home/obs目录下产生了gc.dump文件。

1.下载文件到windows上使用Eclipse Memory Analyzer进行分析。工具下载地址:

https://www.eclipse.org/mat/downloads.php,找到对应的版本

OOM的异常排查过程_内存泄露_02

2.从环境上下载outofmemory的dump文件。dump文件太大,工具无法打开的问题,需要先调整工具参数:

OOM的异常排查过程_内存泄露_03

MemoryAnalyzer.ini文件中的-Xmx参数,比dump文件大才行。

OOM的异常排查过程_内存泄露_04

3. 打开dump文件,dump文件16GB,但大开后显示total size只有100多MB。如果真实内存只有100多MB肯定不会outofmemory,这个时候需要将开启unreachable objects,因为没有引用的对象占用内存,工具默认不显示它们。需要安装下面步骤开启:

window-->Preferences-->memory Analuzer-->勾选keep unreachable objects-->apply and close。如下图所示:

OOM的异常排查过程_内存泄露_05

 

4. mat工具提供自动分析内存点,点击“leak suspects”,就可以看到最大内存占用的,如下图的灰色部分,然后查看详情就可以找到谁占用内存。

OOM的异常排查过程_内存泄露_06