java - 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
这实际上意味着发生了以下情况
- 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)
那么问题来了,怎么做?
PS 另外,当我将所有内容更改为静态时,程序会完全改变它的行为,所以即使有时我会得到超过 3 个结果。
编辑:当我运行它时,-Xss228k
我总是得到
1281
1280
-1281
但是-Xss1m
再次运行会使我遇到随机堆栈大小,有时还会出现上述情况。
解决方案
运行您的代码可能会导致一些其他可能的输出。在我的 PC(Java 8、Windows)上,我主要得到一对值,例如:
7053
-7055
但在极少数情况下,我会得到:
9667
9666
-9667
不建议捕获 any java.lang.Error
,这是 JVM 可能无法恢复的异常情况。
推荐阅读
- python - 如何改变 Alexa 的通话速度?
- sql - oracle在哪里存储撤消数据?在内存或硬盘中
- javascript - 触发选择以从 Vuejs 中的函数打开
- c# - 如何在 ASP .NET 的 configureServices 函数中获取连接字符串
- c# - 使用持续时间而不是速度的 MoveTowards
- java - 使用无法修改的类时避免使用 instanceof 的最佳设计模式?
- aframe - 无法在 A-Frame 中的元素上设置 angularVelocity
- c# - 忽略在 C# .NET 中抛出的特定异常
- amazon-web-services - AOP 与 Spring 和 X-Ray SDK for Java
- r - 将单独的日期时间字段组合到一个 date_time 字段