一、什么是内存溢出(OOM)
JVM 在需要分配内存时,如果堆、元空间或直接内存耗尽,就会抛出 OOM。常见类型包括:
Java heap space:堆空间不足GC overhead limit exceeded:长时间 Full GC 效果仍然不好Metaspace:类元数据过多Direct buffer memory:堆外内存耗尽
无论哪种类型,本质都是内存资源无法满足当前分配请求。
二、常见导致 OOM 的原因
最主要的几个场景:
1. 一次读取太多数据
例如一次性加载整张大表、大文件。
2. 本地缓存无限增长
如静态 List、Map 无限追加对象,没有上限。
3. 内存泄漏
对象已无业务用途,但仍被引用导致无法被 GC 回收。 常见泄漏点包括:
- ThreadLocal 未 remove
- 静态集合持有大量对象
- 单例对象持有上下文数据
4. JVM 堆配置过小
堆限制远低于实际业务需求。
三、通过 Demo 快速复现 OOM(含命令)
为了快速演示 OOM,从而获取 Dump,我们可以通过一个小 Demo 服务来制造 OOM。
假设应用提供了一个接口 /cacheOrders,每次请求会往静态集合中塞入大对象。
第一步:启动服务并开启 OOM 自动 Dump
java -Xms200m -Xmx200m \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/opt/data/dump \
-jar oom-1.0-SNAPSHOT.jar
参数解释:
-Xms200m -Xmx200m:将堆固定为 200MB,便于快速触发 OOM-XX:+HeapDumpOnOutOfMemoryError:发生 OOM 时自动生成 Dump-XX:HeapDumpPath:Dump 输出目录
第二步:循环请求接口造数据
while true; do curl "http://192.168.121.140:8080/cacheOrders?count=1000" > /dev/null 2>&1; done
这一行脚本会不断发送请求,让服务器将大量数据塞入静态缓存。堆只有 200MB,很快会出现:
java.lang.OutOfMemoryError: Java heap space
同时在 /opt/data/dump 下生成 .hprof 文件。
到这里,复现 OOM 的过程就完成了,接下来进入最关键的环节——Dump 分析。
四、使用 MAT 分析 Dump
Heap Dump 是定位 OOM 的关键依据。Eclipse Memory Analyzer(MAT)是最常用的分析工具。
下面是从导入 dump 到找到问题的完整步骤。


