【问题标题】:How java handles StackOverflowError?java如何处理StackOverflowError?
【发布时间】:2018-11-17 15:12:55
【问题描述】:

这是我的示例应用

public class Main {

    private long[] exceptionLevels = new long[1000];
    private int index;

    public static void main(String... args) {
        Main main = new Main();
        try {
            main.foo(0);
        } finally {
            Arrays.stream(main.exceptionLevels)
                    .filter(x -> x != 0)
                    .forEach(System.out::println);
        }
    }

    private void foo(int level) {
        try {
            foo(level + 1);
        } catch (StackOverflowError e) {
            exceptionLevels[index++] = level;
            bar(level + 1);
        }
    }

    private void bar(int level) {
        try {
            bar(level + 1);
        } catch (StackOverflowError e) {
            exceptionLevels[index++] = -level;
        }
    }
}

有时,当我运行应用程序时,我会看到这样的结果

8074
8073
-8074

这实际上意味着发生了以下情况

  • foo(8073) 调用 foo(8074)
  • foo(8074) 调用 foo(8075) 死了
  • foo(8074) 记录自己并调用 bar(8075) 死亡
  • foo(8074) 死亡,foo(8073) 捕获它,记录自身并调用 bar(8074)
  • bar(8074) 调用 bar(8075) 死亡,所以 bar(8074) 记录自己
  • 从所有方法返回,优雅地关闭

我明白了,一切都很好。所以有一个可以理解的获取模式

X, X-1, -X

对于呼叫X的一些最高级别

但有时,调用 Main 会产生这种输出

6962
6961
-6963

其实是

X, X-1, -(X+1)

所以问题是,怎么做?

附:此外,当我将所有内容更改为静态时,程序会完全改变它的行为,所以即使有时我会得到超过 3 个结果。

编辑:当我用-Xss228k 运行它时,我总是得到

1281
1280
-1281

但使用-Xss1m 再次运行会使我遇到随机堆栈大小,有时还会出现上述情况。

【问题讨论】:

  • 我不确定你在问什么;您正在溢出堆栈,然后尝试向其添加更多内容,因此显然结果将出乎意料。
  • 这不是随机科学,对吧?结果必须有一些解释

标签: java stack-overflow


【解决方案1】:

运行您的代码可能会产生一些其他可能的输出。在我的 PC(Java 8、Windows)上,我主要得到如下一对值:

7053
-7055

但在极少数情况下我会得到:

9667
9666
-9667

不建议捕获任何java.lang.Error,这是JVM可能无法恢复的异常情况。

【讨论】:

  • 那你觉得流程怎么样?
  • 可能堆栈溢出,数据损坏,无法预测流量?胡乱猜测,但似乎是随机的。
猜你喜欢
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多