finally块中的堆栈溢出错误处理 [英] Stack overflow error handling in finally block

查看:163
本文介绍了finally块中的堆栈溢出错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a program in java, which runs infinite times.

程序代码:

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

输出:此程序无限运行,不断打印两者sysouts。

OUTPUT : this program runs infinitely, by constantly printing both the sysouts.

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

My question : At some point, it starts throwing StackOverflowErrors from the try block and so it reaches the finally block, where we are again calling this function recursively. But how is the recursive function in the finally block being executed as we already facing a StackOverflowError?

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

How does the JVM handle this situation? Will the same behavior occur if we get OutOfMemoryErrors too?

推荐答案

问题是你的示例程序是病态的。它不起作用,它无法工作。

The problem is that your example program is pathological. It won't work, and it can't work.


但是我们已经面对的是finally块中的递归函数如何执行 StackOverflowError 。?

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

There is a rather complicated sequence of calls going on. Lets assume that the stack can hold 3 frames. A "hand execution" gives us a sequence of calls / call-stack snapshots as follows:

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次调用

As you can see with a stack of depth 3, we made 7 calls, 4 of which failed with a stack overflow. If you do the hand execution for a stack of depth 4, you will get 15 calls, 5 => 31. The pattern is N => 2**N - 1 calls.

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

In your case, the default stack is going to be able to accommodate hundreds, or even thousands of recursive calls.

说N = 100. 2 ** 100是一个非常大的调用。它不是无限的,但在程序终止之前你可能已经死了。

Say N = 100. 2**100 is a very large number of calls. It is not infinite, but you will probably be dead before the program terminates.


JVM如何处理这种情况?

How does the JVM handle this situation?

如上所述。 JVM没有做任何特别的事情。 有效无限循环行为完全完全到你的程序编写方式。

As above. The JVM is not doing anything special. The "effectively infinite loop" behaviour is entirely down to the way that your program is written.


请问如果我们得到 OutOfMemoryError 也会出现同样的行为?

Will the same behaviour occur if we get OutOfMemoryErrors too?

呃......这取决于你的程序。但我相信你可以编写一个表现出类似行为模式的示例程序。

Erm ... it depends on your program. But I'm sure you could concoct an example program that exhibited a similar pattern of behaviour.

这篇关于finally块中的堆栈溢出错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆