Java OutOfMemoryError 异常原理与实战排查
在 Java 开发中,内存溢出异常是影响程序稳定性的关键问题。了解其原理和应对方法,对开发者至关重要。
一、Java 堆溢出
原理
Java 堆用于存储对象实例。不断创建对象,且阻止垃圾回收器回收,对象数量超出堆容量时,就会引发堆溢出。
示例代码
// VM Args: -Xmx20m -Xms20m -XX:+HeapDumpOnOutOfMemoryError
public class HeapOOM {
static class OOMObject {}
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<>();
while (true) {
list.add(new OOMObject());
}
}
}
解决思路
- 利用内存映像分析工具(如 Eclipse Memory Analyzer)分析堆转储快照。
- 区分内存泄漏和内存溢出:若存在无用对象长期占用内存,是内存泄漏;若对象都有用但堆空间不足,可调整堆参数(
-Xmx与-Xms),并优化代码减少内存占用。
二、虚拟机栈和本地方法栈溢出
原理
- 线程请求栈深度超虚拟机允许值,抛出
StackOverflowError。 - 虚拟机栈若支持动态扩展,扩展时内存申请失败,抛出
OutOfMemoryError(HotSpot 不支持栈动态扩展)。
示例代码
测试 StackOverflowError
// VM Args: -Xss128k
public class JavaVMStackSOF {
private int stackLength = 1;
public void stackLeak {
stackLength++;
stackLeak();
}
Throwable {
();
{
oom.stackLeak();
} (Exception e) {
System.out.println( + oom.stackLength);
e;
}
}
}


