OOM内存溢出分析排查-案例

2021/02/10

资料参考

一、JVM配置-内存溢出时自动dump进程堆栈信息

1.发现内存溢出时日志或者服务器监控:“Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded”

2.检查启动shell脚本或者命令中JVM配置,是否指定heap大小,是否配置HeapDumpOnOutOfMemoryError

JAVA_OPTS = "-Xms2048m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/java_heapdump.hprof"     
nohup java $JAVA_OPTS -jar demo-server.jar --spring.profiles.active=pro 

3.补充JVM配置(如缺少)

JAVA_OPTS = "-Xms2048m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/java_heapdump.hprof"       
nohup java $JAVA_OPTS -jar demo-server.jar --spring.profiles.active=pro

二、主动dump指定进程实时堆栈信息

1.top命令查看进程id

2.使用jmap命令生成dump文件,1123指java程序pid

jmap -dump:format=b,file=demo-server.dump 1123

三、Dump分析

3.1 使用Jvisualvm分析dump文件

C:\Program Files\Java\jdk1.8.0_171\bin\jvisualvm.exe

3.2 使用MAT分析分析dump文件

1.下载 解压 MemoryAnalyzer-1.9.2.20200115-win32.win32.x86_64

2.修改配置MemoryAnalyzer.ini
-Xmx4096m

3.启动MemoryAnalyzer.exe

4.加载dump文件
file->open file

5.Histogram:查看实例数及大小

6.dominator_tree 查看占用堆内存最大的线程
本例:ibatis的查询结果集98.8万条记录导致内存溢出

7.thread_overview 查看线程详情,找到最大对象定位到代码或者sql
定位到org.apache.ibatis.executor.resultset.DefaultResultSetHandler

定位到具体sql
查看sql参数

8.问题及代码定位:
问题确认:取sql执行,发现关联多张表,查询慢,且查询未分页,条件过滤少,返回结果近百万条,导致内存直接溢出
问题解决:优化sql或者代码

Post Directory

扫码关注公众号:暂无公众号
发送 290992
即可立即永久解锁本站全部文章