美文网首页
java.lang.StackOverflowError——如何

java.lang.StackOverflowError——如何

作者: quiterr | 来源:发表于2017-03-27 21:57 被阅读0次

原文链接:https://examples.javacodegeeks.com/java-basics/exceptions/java-lang-stackoverflowerror-how-to-solve-stackoverflowerror/

StackOverflowError在程序栈空间耗尽时抛出,通常是深度递归导致。StackOverflowError继承了VirtualMachineError类,后者表示JVM已被破坏或资源耗尽。更进一步,VirtualMachineError继承自Error类,应用程序不应该捕获这种严重的错误。不要再throw语句里面抛出这样的错误,因为这些错误是不应该发生的异常条件。StackOverflowError从Java 1.0版本就已存在。

StackOverflowError构造函数

StackOverflowError()StackOverflowError(String s),后者的String参数指明了抛出错误的类名。

The StackOverflowError in Java

当一个函数被Java程序调用的时候,就会在调用栈上分配栈帧。栈帧包含被调用函数的参数、局部变量和返回地址。返回地址指示了当函数执行完毕之后下一步该执行哪里。如果创建栈帧时没有内存空间,JVM就会抛出StackOverflowError。

最常见的耗尽Java栈的案例是递归。在递归操作中,函数执行时会调用自己。使用递归要小心,以免抛出StackOverflowError错误。如下的例子演示了递归如何抛出StackOverflowError:

public class StackOverflowErrorExample {
    
    public static void recursivePrint(int num) {
        System.out.println("Number: " + num);
        
        if(num == 0)
            return;
        else
            recursivePrint(++num);
    }
    
    public static void main(String[] args) {
        StackOverflowErrorExample.recursivePrint(1);
    }
}

如果num为0,递归就会终止,但是这里一开始传入1,每次递归都自增1,递归永远不会终止。
使用-Xss1M参数指定线程栈空间大小为1M,这个例子的执行结果如下:

Number: 1
Number: 2
Number: 3
...
Number: 6262
Number: 6263
Number: 6264
Number: 6265
Number: 6266
Exception in thread "main" java.lang.StackOverflowError
        at java.io.PrintStream.write(PrintStream.java:480)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
        at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
        at java.io.PrintStream.write(PrintStream.java:527)
        at java.io.PrintStream.print(PrintStream.java:669)
        at java.io.PrintStream.println(PrintStream.java:806)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:4)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
        ...

More about the StackOverflowError in Java

下面的例子演示了类之间有循环关系时的风险。

class A {
    private int aValue;
    private B bInstance = null;
    
    public A() {
        aValue = 0;
        bInstance = new B();
    }
    
    @Override
    public String toString() {
        return "";
    }
}

class B {
    private int bValue;
    private A aInstance = null;
    
    public B() {
        bValue = 10;
        aInstance = new A();
    }
    
    @Override
    public String toString() {
        return "";
    }
}

public class StackOverflowErrorToStringExample {
    public static void main(String[] args) {
        A obj = new A();
        System.out.println(obj.toString());
    }
}

当创建A对象的时候需要创建B对象,创建B对象的时候又要创建A对象,在两个类之间形成了循环依赖,最终导致StackOverflowError。输出结果:

Exception in thread "main" java.lang.StackOverflowError
    at main.java.B.(StackOverflowErrorToStringExample.java:24)
    at main.java.A.(StackOverflowErrorToStringExample.java:9)
    at main.java.B.(StackOverflowErrorToStringExample.java:24)
    at main.java.A.(StackOverflowErrorToStringExample.java:9)
    at main.java.B.(StackOverflowErrorToStringExample.java:24)
    at main.java.A.(StackOverflowErrorToStringExample.java:9)
    ...

如何处理StackOverflowError

  • 最简单的方法就是细致的检查stack trace,找出行号的重复模式。这些重复的行号代表了被递归调用的代码。仔细审查代码,理解为何递归不终止。
  • 如果你确认递归实现没有问题,你可以通过-Xss参数增加栈的大小,这个参数可以在项目配置或命令行指定。

相关文章

  • JVM-OOM

      StackOverflowError(java.lang.StackOverflowError):   Jav...

  • java.lang.StackOverflowError——如何

    原文链接:https://examples.javacodegeeks.com/java-basics/excep...

  • Android 错误记录

    1、android exception:java.lang.StackOverflowError 遇见这个错误提...

  • 虚拟机栈溢出

    错误原因:java.lang.StackOverflowError 栈内存溢出 栈溢出产生递归调用,循环遍历是不会...

  • java.lang.StackOverflowError at

    log4j导致栈溢出,报错内容如下: java.lang.StackOverflowErrorat org.apa...

  • java.lang.StackOverflowError: st

    在使用Fragment的时候,无意间会发生这个异常 那么检查你的onCreateView()中的代码,看看View...

  • java.lang.StackOverflowError: st

    问题描述: 内存溢出了,程序里可能是有死循环或递归调用 解决方法: 我这边引入的原因是在加载布局的时候,没有设置a...

  • 有易效能重塑线上生活不再只是空想

    如何唤醒身体、如何开始运动、如何合理饮食,如何收集事情、如何分类管理、如何开始记录、如何开始改变习惯,如何...

  • 第四个月小结

    如何呼吸,如何练眼神,如何走路,如何写作,如何学习,如何修身养性,如何提出好问题,如何练情商与智商,如何把所有的事...

  • 简:过自己的人生 看自己的风景

    图文/喜悦 一 不管别人 如何富有 如何优秀 如何潇洒 如何智慧 如何能说会道 如何体面优雅 如何临危不惧 如何从...

网友评论

      本文标题:java.lang.StackOverflowError——如何

      本文链接:https://www.haomeiwen.com/subject/lkrrottx.html