StackOverflowError

StackOverflowError

背景

  • JVM的Error

定义

  • StackOverflowError 是 JVM 抛出的一种虚拟机栈相关的错误(Error),属于 VirtualMachineError 的子类,它表示:JVM 虚拟机栈(或本地方法栈)的深度超过了虚拟机允许的最大深度,简单说就是 “方法调用的栈帧层数太多,把栈内存撑爆了”。
  • 注意:
    • 它和 OutOfMemoryError 都属于 Error(严重错误),而非 Exception(普通异常),程序无法通过 try-catch 优雅恢复,通常会直接终止线程;
    • 它本质是栈内存的 “深度溢出”,而 OOM 是内存的 “容量不足”,两者成因和场景完全不同。

出现StackOverflowError原因

  • 核心原因是方法调用的递归深度 / 栈帧数量超出了虚拟机栈的最大限制,具体分为俩类:

    • 1.无限递归调用:

      • 方法直接 / 间接调用自身,且没有终止条件,导致栈帧不断压入虚拟机栈,最终超出栈内存上限。

      • 代码演示:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        public class StackOverflowExample {
        // 递归方法,无终止条件
        public static void recursiveCall() {
        recursiveCall(); // 方法自己调用自己,无限循环
        }

        public static void main(String[] args) {
        try {
        recursiveCall();
        } catch (StackOverflowError e) {
        System.out.println("触发 StackOverflowError:" + e.getMessage());
        e.printStackTrace();
        }
        }
        }
    • 2.其它原因

      • 单个方法的栈帧过大:方法内定义了大量局部变量、大数组,导致单个栈帧占用内存过多,少量调用就占满栈空间;
      • JVM 栈内存配置过小:通过 -Xss 参数设置的虚拟机栈内存上限太低(比如 -Xss128k),正常的方法调用深度也会超出限制。

总结

  • StackOverflowError 是虚拟机栈深度超限导致的错误,核心是方法调用层数过多(如无限递归);
  • 它和 OOM 不同:OOM 是内存 “容量不足”(堆 / 元空间等),StackOverflowError 是栈 “深度超标”;
  • 解决思路:排查无限递归(加终止条件)、减少方法嵌套深度、通过 -Xss 适当调大栈内存(如 -Xss1m)。