java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java内存溢出OOM

Java内存溢出(OOM)场景总结与排查实践

作者:何以解忧,唯有..

在 Java 应用开发与运维中,内存溢出是最常见也最棘手的问题之一,本文系统总结 Java 中各类 OOM 的典型场景、触发原因、排查思路与预防手段,帮助你在遇到 OOM 时能快速定位并解决,需要的朋友可以参考下

1. 引言

在 Java 应用开发与运维中,内存溢出(OutOfMemoryError,简称 OOM)是最常见也最棘手的问题之一。它不像普通异常那样可以通过 try-catch 捕获后继续运行,而是往往直接导致进程崩溃或服务不可用。本文系统总结 Java 中各类 OOM 的典型场景、触发原因、排查思路与预防手段,帮助你在遇到 OOM 时能快速定位并解决。

2. OOM 的本质与分类

OOM 的本质是 JVM 在申请内存时无法获得足够的可用空间。根据内存区域的不同,OOM 可以划分为以下几类:

3. 堆内存溢出(Java heap space)

3.1 典型场景

堆内存溢出是最常见的 OOM 类型,常见于以下场景:

3.2 排查思路

# 启动时开启堆转储,OOM 时自动生成 dump 文件
java -Xmx2g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/dump/ app.jar

拿到 dump 文件后,使用 MAT(Memory Analyzer Tool)或 JProfiler 分析:

  1. 查看 Dominator Tree,找出占用内存最大的对象。
  2. 查看 Leak Suspects,定位疑似泄漏点。
  3. 结合业务代码,确认对象是否被错误地长期持有。

3.3 预防手段

4. 元空间溢出(Metaspace)

4.1 典型场景

元空间存放类的元数据,溢出常见于:

4.2 排查思路

# 查看元空间使用情况
jstat -gcmetacapacity <pid>
# 开启类加载跟踪
java -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:+TraceClassLoading app.jar

重点检查是否存在 ClassLoader 泄漏:每次热部署后,旧的 ClassLoader 是否被正确回收。

4.3 预防手段

5. 栈溢出(StackOverflowError)

5.1 典型场景

5.2 排查思路

栈溢出会直接打印调用栈,定位到具体方法即可。常见原因:

5.3 预防手段

6. 直接内存溢出(Direct buffer memory)

6.1 典型场景

6.2 排查思路

# 查看直接内存使用情况
jcmd <pid> VM.native_memory summary

直接内存不归堆管理,-Xmx 无法限制它,需通过 -XX:MaxDirectMemorySize 单独控制。

6.3 预防手段

7. GC 开销超限(GC overhead limit exceeded)

7.1 典型场景

当 JVM 花费超过 98% 的时间进行 GC,但回收不到 2% 的堆内存时,会抛出此异常。本质上是堆内存严重不足或存在内存泄漏。

7.2 排查思路

7.3 预防手段

8. 无法创建本地线程(unable to create new native thread)

8.1 典型场景

8.2 排查思路

# 查看进程线程数
cat /proc/<pid>/status | grep Threads
# 查看系统线程数限制
ulimit -u

结合线程 dump(jstack)分析线程都在做什么,是否存在线程泄漏。

8.3 预防手段

9. 总结

OOM 类型典型原因排查工具预防手段
Java heap space对象过多、内存泄漏MAT、jmap合理堆大小、流式处理
Metaspace类加载过多jstat、TraceClassLoading控制动态代理、热部署
StackOverflowError递归过深调用栈直接定位递归改循环
Direct buffer memoryNIO 堆外内存过多jcmd、NMT控制 MaxDirectMemorySize
GC overhead limit堆严重不足GC 日志、堆转储优化堆与 GC 策略
unable to create native thread线程数超限jstack、ulimit有界线程池

遇到 OOM 时,建议按以下步骤处理:

  1. 先看异常信息,确定是哪种 OOM。
  2. 开启堆转储与 GC 日志,复现问题。
  3. 使用 MAT、jstack、jstat 等工具定位根因。
  4. 修复代码或调整 JVM 参数。
  5. 增加监控告警,提前发现内存增长趋势。

以上就是Java内存溢出(OOM)场景总结与排查实践的详细内容,更多关于Java内存溢出OOM的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文