加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 在递归调用时的StackOverflowError

发布时间:2020-12-14 05:41:33 所属栏目:Java 来源:网络整理
导读:问题是严格的理论,但我找不到答案.考虑这个简短的程序: public class SBtst { int i = 0; public static void main(String[] args) { new SBtst().rec(); } public void rec() { System.out.println("rec is called "+i++); try { rec(); } catch (StackOve
问题是严格的理论,但我找不到答案.考虑这个简短的程序:
public class SBtst {

    int i = 0;

    public static void main(String[] args) {
        new SBtst().rec();
    }

    public void rec() {
        System.out.println("rec is called "+i++);
        try {
            rec();
        } catch (StackOverflowError soe) {
            System.out.println("completed "+soe.getStackTrace().length);
        }
    }

}

执行后,我得到的输出类似于:

rec is called 10472
rec is called 10473
rec is called 10474Recursion completed 1024

问题是:

>为什么没有println()完成新行,因为据了解,当执行下一个rec()调用时,应该抛出一个错误,并且是完成后的println()
>为什么stackTrace数组中只有1024个元素,但是等于10474?这是否意味着并不是每个调用都在堆栈跟踪中?

解决方法

为什么例外显然是从println中抛出来的?

Why didn’t println() complete a new line? As I understand,the exception should be thrown when the next rec() call is executed,but that would be after println() has completed.

你的理解不太正确.在某些时候,堆栈看起来像:

…
rec()
  rec()
    rec()
      println()

Println也会消耗资源(参见mattingly890’s answer),没有理由在这一点上无法达到极限.

为什么堆栈跟踪包含比实际使用的帧少的帧?

Why do I get only 1024 elements in the stack trace,even though at least 10474 were used? Does it mean that not every call is in the stack trace?

看看getStackTrace()的文档:

Provides programmatic access to the stack trace information printed
by printStackTrace(). Returns an array of stack trace elements,each
representing one stack frame. The zeroth element of the array
(assuming the array’s length is non-zero) represents the top of the
stack,which is the last method invocation in the sequence. Typically,
this is the point at which this throwable was created and thrown. The
last element of the array (assuming the array’s length is non-zero)
represents the bottom of the stack,which is the first method
invocation in the sequence.

Some virtual machines may,under some circumstances,omit one or more
stack frames from the stack trace.
In the extreme case,a virtual
machine that has no stack trace information concerning this throwable
is permitted to return a zero-length array from this method. Generally
speaking,the array returned by this method will contain one element
for every frame that would be printed by printStackTrace.
Writes to
the returned array do not affect future calls to this method.

在Peter Lawrey found the documentation的评论中,堆栈大小提到1024个默认限制:

07003

-XX:ThreadStackSize=512

Thread Stack Size (in Kbytes). (0 means use default stack size)
[Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier);
Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all
others 0.]

可能还有其他因素也起作用.例如,这些问题提到另外两个选项:

> how to expand size of Java stack trace to see bottom of stack? (triggering a stack overflow)(-XXMaxJavaStackTraceDepth)
> How to avoid the 1024 lines of Java exception stack limit(-Xss)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读