首页 > 解决方案 > java如何处理StackOverflowError?

问题描述

这是我的示例应用程序

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

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

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

X, X-1, -X

一些最高级别的通话X

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

6962
6961
-6963

这实际上是

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

那么问题来了,怎么做?

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

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

1281
1280
-1281

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

标签: javastack-overflow

解决方案


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

7053
-7055

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

9667
9666
-9667

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


推荐阅读