Java内存溢出实战:堆溢出与栈溢出的复现及原因解析

小满
小满
发布时间:2026-10-14 | 5人浏览过
原创

Java开发中经常遇到因内存管理不当导致的程序崩溃。本文将直接演示两种典型的内存溢出场景:通过不断创建对象引发的"堆溢出"和通过无限递归引发的"栈溢出",并展示对应的错误日志,帮助初学者理解JVM内存结构的差异。

堆溢出(OOM)

Java堆内存用于存储对象实例。当代码试图在堆中创建新对象,而堆空间不足以容纳时,JVM会抛出java.lang.OutOfMemoryError: Java heap space错误。

示例代码:

import java.util.ArrayList;
import java.util.List;

/**
 * 堆溢出示例
 */
public class HeapOutofMemory {
    public static void main(String[] args) {
        // 使用ArrayList集合持续占用堆内存
        List<HeapOutofMemory> list = new ArrayList<>();
        
        while (true) {
            // 不断向列表中添加当前类的实例,直到内存耗尽
            list.add(new HeapOutofMemory());
        }
    }
}

运行结果:

java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3210) at java.util.Arrays.copyOf(Arrays.java:3181) at java.util.ArrayList.grow(ArrayList.java:265) ... ...

栈溢出(SOF)

Java虚拟机栈主要用于描述Java方法执行的内存模型。每个方法在执行时会创建一个栈帧,用于存储局部变量表、操作数栈等。如果线程请求的栈深度大于虚拟机所允许的深度,就会抛出java.lang.StackOverflowError。

最常见的情况是方法进行了无限递归调用。

示例代码:


/**
 * 栈溢出示例
 */
public class StackOverflow {
    public static void main(String[] args) {
        new StackOverflow().test();
    }

    public void test() {
        // 方法内部无终止条件的递归调用
        test();
    }
}

运行结果:

Exception in thread "main" java.lang.StackOverflowError at StackOverflow.test(JavaDemo.java:14) at StackOverflow.test(JavaDemo.java:14) at StackOverflow.test(JavaDemo.java:14) ...

关键区别总结:

  • 堆溢出通常是因为对象存活时间过长或数量过多,需要调整堆大小(-Xmx)或优化对象引用逻辑。
  • 栈溢出通常是代码逻辑问题(如死循环递归),可通过检查递归终止条件或在启动参数中增加栈容量(-Xss)临时缓解,但根本解决需修复代码逻辑。

以上就是Java内存溢出中堆溢出与栈溢出详细内容的解析,更多关于Java JVM内存管理的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表