0

我见过像for ( ; ; )和这样的循环while (true )

许多程序使用这种技术来无限运行循环。是否可以使用递归来应用相同的技术?

4

3 回答 3

4

不会。每一级递归都会在堆栈上放置一个新帧,供内部使用和局部变量使用。

随着深度的增加,您最终将到达专用于该堆栈的有限内存的尽头。为最后一帧和任何 C++ 区域保留了一个阴影区域,因此达到该区域足以使堆栈溢出。

Java 方法生成的代码检查堆栈空间在堆栈末端的固定距离是否可用,以便可以在不超出堆栈空间的情况下调用本机代码。靠近堆栈末端的这个距离称为“影子页”。影子页面的大小在 3 到 20 页之间,具体取决于平台。此距离是可调的,因此本机代码需要超过默认距离的应用程序可以增加影子页面大小。

这用于您输入无法可靠检测堆栈结束的本机代码的情况。如果堆栈上没有足够的空间来进行本机代码中的任何递归或调用,则可能会发生真正的硬堆栈溢出并带来令人讨厌的后果。

注意Java不进行尾递归优化,所以编译器不会把递归变成迭代。

于 2013-08-14T15:34:22.860 回答
1

每次函数调用自身时,都会消耗堆栈空间。由于堆栈是有限资源,程序最终会耗尽堆栈空间并被杀死。

也就是说,可以在支持尾调用优化的 JVM 上创建无限循环。

但是,我不知道有任何这样的 JVM。有关详细讨论,请参阅JVM 是否阻止尾调用优化?

于 2013-08-14T15:48:21.833 回答
-1

“如果有机会在java中使用递归无限运行程序?”

-不。但似乎某些方法或代码片段试图无限运行,但最终它们会出错。下面的 main 方法无限调用自身。您可能认为您正在无限地做某事,但取决于平台的一定数量的堆栈最终会用完,jvm 会抛出堆栈溢出错误。所以,从技术上讲,不,你不能。

public static void main(String... args){

    main(args);

}

上面是一个坏递归的例子,最终会导致堆栈溢出错误。

根据混淆进行编辑。

于 2013-08-14T15:32:39.917 回答