java - finally block 中的堆栈溢出错误处理

标签 java recursion jvm stack-overflow try-finally

我有一个 java 程序,它可以无限次运行。

程序代码:

void asd()
{
    try
    {
        //inside try block
        System.out.println("Inside try !!!");
        asd();
    }
    finally
    {
        //inside finally
        System.out.println("Inside finally !!!");
        asd();
    }
}

输出:该程序通过不断打印两个系统输出来无限运行。

我的问题:在某些时候,它开始从 try block 中抛出 StackOverflowErrors,因此它到达 finally block ,我们再次递归地调用此函数。但是当我们已经面临 StackOverflowError 时,finally block 中的递归函数是如何执行的呢?

JVM 是如何处理这种情况的?如果我们也得到 OutOfMemoryErrors,是否会发生同样的行为?

最佳答案

问题是您的示例程序是病态的。行不通,行不通。

But how the recursive function in the finally block gets executed as we already facing StackOverflowError.?

正在进行一系列相当复杂的调用。让我们假设堆栈可以容纳 3 帧。 “手动执行”为我们提供了一系列调用/调用堆栈快照,如下所示:

asd()
asd() > try
asd() > try > asd() 
asd() > try > asd() > try 
asd() > try > asd() > try > asd() // Stack Overflow!
asd() > try > asd() > finally
asd() > try > asd() > finally > asd() // Stack Overflow!
asd() > finally
asd() > finally > asd()
asd() > finally > asd() > try
asd() > finally > asd() > try > asd() // Stack Overflow!
asd() > finally > asd() > finally
asd() > finally > asd() > finally > asd() // Stack Overflow!

END

如您所见,对于深度为 3 的堆栈,我们进行了 7 次调用,其中 4 次因堆栈溢出而失败。如果您对深度为 4 的堆栈进行手动执行,您将获得 15 次调用,5 => 31。模式为 N => 2**N - 1 次调用

在您的情况下,默认堆栈将能够容纳数百甚至数千个递归调用。

假设 N = 100。2**100 是一个非常大的调用数。它不是无限的,但你可能会在程序终止之前就死了。

How does the JVM handle this situation?

如上。 JVM 没有做任何特别的事情。 “有效无限循环”行为完全取决于您编写程序的方式。

Will the same behaviour occur if we get OutOfMemoryErrors too?

呃……这取决于你的程序。但我相信您可以编写一个示例程序来展示类似的行为模式。

关于java - finally block 中的堆栈溢出错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17836120/

相关文章:

java - 无法从其他方法返回值

java - 正则表达式获取最后一个值

javascript - 在 Javascript 中执行尾端递归时是否必须手动释放内存

haskell - 专门用于列表的组织同态、对称同态和 future 同态

c# - ASP.NET 中的递归 TreeView

Java 正则表达式 : Parsing a string with two matching substrings

android - OutOfMemory 错误,但有可用内存

java - 反编译混淆的java字节码

java - 如何查看java进程的cpu使用情况

java - 如何查找java项目中未使用/死的代码