当前位置: 首页 > 知识库问答 >
问题:

java如何处理StackOverflowError?

冯德宇
2023-03-14
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(8075)
  • foo(8074)记录自身并调用bar(8075),
  • foo(8074)死亡,foo(8073)捕获它,记录自己并调用bar(8074)
  • bar(8074)调用bar(8075),bar(8074)死亡,因此bar(8074)记录自己
  • 从所有方法返回,并优雅地关闭

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

X, X-1, -X

对于调用的最大级别x

6962
6961
-6963
X, X-1, -(X+1)

附言。而且,当我把所有东西都改为静态时,程序完全改变了它的行为,所以有时我会得到3个以上的结果。

编辑:当我用-xss228k运行这个函数时,我总是得到

1281
1280
-1281

但是,使用-xss1m运行时,我再次遇到了随机堆栈大小,有时还会遇到上面描述的情况。

共有1个答案

虞滨海
2023-03-14

运行代码可能导致很少其他可能的输出。在我的个人电脑(Java8,Windows)上,我通常会得到两个值,比如:

7053
-7055

但在很少的情况下,我会:

9667
9666
-9667

不建议捕捉任何java.lang.error,这是一种异常情况,JVM可能无法从中恢复。

 类似资料:
  • 问题内容: 如何用Java 处理? 问题答案: 我不确定“句柄”是什么意思。 您当然可以捕获该错误: 但这很可能是个坏主意,除非您确切地知道自己在做什么。

  • 问题内容: 它是否只是在每次除法后检查除数是否等于零(即使在JIT版代码中)? 我的意思是VM如何在不被OS杀死的情况下设法引发异常? 问题答案: 在一个Unix环境,在这种划分被零是通过主导,JVM将已安装的陷阱的信号处理程序,进而S上的。如果您对内部结构感兴趣,请参见例如 我认为OP提出的要求是基于这样一个事实,即直到/除非有处理程序到位,大多数进程都会在接收到此信号时采取默认操作,即终止操作

  • 有没有办法过滤掉所有大于最大值的值,这些值可以存储在使用StreamAPI的Long中?目前的情况是,您可以在前端使用简单的搜索条搜索某些客户,通过使用他们的ID。例如:如果您在这两个ID之间放置一个“隔离器”,一切都正常。但是如果您忘记了“隔离器”,我的代码试图将解析为Long,我想这就是问题所在。这会在尝试搜索后导致一个数字格式异常。有没有办法过滤掉这些因为太大而无法解析为Long的数字? 谢

  • 问题内容: 在开发高度基于XML的Java应用程序时,我最近在Ubuntu Linux上遇到了一个有趣的问题。 我的应用程序使用Java Plugin Framework ,似乎无法将dom4j创建的XML文档转换为Batik的 SVG规范实现。 在控制台上,我了解到发生了错误: 我认为问题是由来自JVM的原始类加载器与插件框架部署的类加载器之间的冲突引起的。 据我所知,不可能为框架指定一个类加载

  • 问题内容: 在开发一个高度基于XML的Java应用程序时,我最近在Ubuntu Linux上遇到了一个有趣的问题。 我的应用程序使用Java Plugin Framework ,似乎无法将dom4j创建的XML文档转换为Batik的 SVG规范实现。 在控制台上,我了解到发生了错误: 我认为问题是由JVM的原始类加载器与插件框架部署的类加载器之间的冲突引起的。 据我所知,不可能为框架指定一个类加载

  • 问题内容: Java如何确定分配线程或进程的内核?有什么办法可以控制吗?防止两个大线程在同一内核上执行? 基本上,我要问的是有关Java中多线程如何工作或如何在Java中控制它的更多信息。 问题答案: 您不能为特定线程设置处理器关联。但是,如果将程序分为两个进程,则应该能够将这些进程分配给操作系统级别的特定处理器。 http://www.cyberciti.biz/tips/setting-pro