侧边栏壁纸
博主头像
月伴飞鱼 博主等级

行动起来,活在当下

  • 累计撰写 126 篇文章
  • 累计创建 31 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
JVM

OutOfMemory和StackOverflow的区别是什么?

月伴飞鱼
2025-03-23 / 0 评论 / 1 点赞 / 12 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 定义

  • OutOfMemoryError (OOM):

    • 表示 内存不足,通常在 JVM 尝试分配对象时发现没有足够的堆、元空间或其他内存区域来完成分配。

    • 原因包括:创建过多对象、内存泄漏、配置的内存过小。

  • StackOverflowError (SOE):

    • 表示 栈内存溢出,通常发生在递归调用太深或方法调用层次过多时,导致栈空间耗尽。

    • 该错误通常是由于程序设计问题,如无限递归。

2. 发生的区域

  • OutOfMemory:

    • Java 堆(Heap)空间不足(最常见)。

    • 元空间(Metaspace)不足。

    • 本地内存(Native Memory)不足。

    • 直接内存(Direct Memory)不足。

    • GC 过载导致 GC Overhead Limit Exceeded

  • StackOverflow:

    • 发生在栈内存区域,主要是方法调用栈深度超过栈大小限制。

3. 异常处理

  • OutOfMemory:

    • 是一种 严重错误,需要通过调优代码或调整 JVM 配置来解决。

    • 常见解决方法:

      • 增加堆内存(如 -Xmx)。

      • 分析并修复内存泄漏。

      • 优化对象生命周期。

  • StackOverflow:

    • 程序设计问题,通常通过检查递归逻辑或优化代码调用链来解决。

    • 常见解决方法:

      • 优化递归代码,改为迭代实现。

      • 增加栈大小(如 -Xss)。

4. 代码示例

1. Java 堆溢出(OutOfMemoryError: Java Heap Space)

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

public class HeapOOM {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        while (true) {
            list.add(new Object()); // 不断创建对象导致堆溢出
        }
    }
}

解决方法:通过 -Xmx 参数增加堆内存大小。

2. 栈溢出(StackOverflowError)

public class StackOverflow {
    public static void main(String[] args) {
        recursiveCall(); // 无限递归调用
    }

    public static void recursiveCall() {
        recursiveCall(); // 方法调用自身,导致栈溢出
    }
}

解决方法:优化递归逻辑,或者增加栈大小(-Xss)。

3. 元空间溢出(OutOfMemoryError: Metaspace)

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

public class MetaspaceOOM {
    public static void main(String[] args) {
        while (true) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Object.class);
            enhancer.setUseCache(false);
            enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> proxy.invokeSuper(obj, args1));
            enhancer.create(); // 不断动态生成类导致元空间溢出
        }
    }
}

解决方法:通过 -XX:MaxMetaspaceSize 参数增加元空间大小。

5. 关键区别

特性

OutOfMemoryError

StackOverflowError

发生区域

堆、元空间、本地内存、直接内存

栈内存

常见原因

对象过多、内存泄漏、直接内存超出

递归过深或方法调用层次过多

可预防性

可通过内存分析工具检测和优化

检查递归和调用链

解决方法

调整 JVM 参数或修复代码

优化递归逻辑或增加栈大小

是否涉及程序设计问题

通常是资源配置问题,偶尔是设计问题

通常是程序设计问题

总结

  • OutOfMemoryError:内存不足的表现,通常与资源配置和程序内存使用有关。

  • StackOverflowError:栈溢出问题,通常是程序设计问题,如无限递归或深层调用链。

  • JVM 中合理配置内存参数(堆和栈大小)以及优化代码设计可以避免大多数这类问题。

公众号.png

1
JVM
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
    1. 支付宝打赏

      qrcode alipay
    2. 微信打赏

      qrcode weixin
博主关闭了所有页面的评论