当前位置: 首页 > 面试题库 >

如何预测递归方法的最大调用深度?

太叔天宇
2023-03-14
问题内容

为了估计在给定内存量下递归方法可能实现的最大调用深度,在可能发生堆栈溢出错误之前,用于计算所用内存的(近似)公式是什么?

编辑:

许多人以“取决于”来回答,这是合理的,因此让我们通过一个简单但具体的示例来删除一些变量:

public static int sumOneToN(int n) {
    return n < 2 ? 1 : n + sumOneToN(n - 1);
}

很容易看出,在我的Eclipse IDE中运行该命令时爆炸的次数n不到1000(对我来说这很低)。是否可以在不执行此调用深度限制的情况下进行估算?

编辑:我不禁想到Eclipse的固定最大调用深度为1000,因为我知道了998,但主要是一个,而方法的初始调用是一个,1000总的来说。这太“圆”了,恕我直言,这是一个巧合。我会进一步调查。我只有Dux开销-
Xss vm参数;这是最大堆栈大小,因此Eclipse运行程序必须在-Xss1000某个地方设置


问题答案:

显然,这是JVM特定的,也可能是特定于体系结构的。

我测量了以下内容:

  static int i = 0;
  public static void rec0() {
      i++;
      rec0();
  }

  public static void main(String[] args) {
      ...
      try {
          i = 0; rec0();
      } catch (StackOverflowError e) {
          System.out.println(i);
      }
      ...
  }

使用

Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)

在x86上运行。

使用20MB
Java堆栈(-Xss20m),每次调用的摊销成本在16-17字节左右波动。我所看到的最低值是16.15字节/帧。因此,我得出的结论是开销为16个字节,其余为其他(固定)开销。

一个函数int的成本基本相同,每帧16字节。

有趣的是,一个占用10位的函数ints需要32字节/帧。我不知道为什么成本这么低。

以上结果在将代码进行JIT编译后适用。在编译之前,每帧成本 高得多。我还没有找到一种可靠的方法来估算它。
但是,这确实意味着您没有希望可靠地预测最大递归深度,直到可以可靠地预测是否已对JIT编译了递归函数。

所有这些都通过ulimit128K和8MB 的堆栈大小进行了测试。在两种情况下结果都是相同的。



 类似资料:
  • 为了估计递归方法在给定内存量下可能达到的最大调用深度,在可能发生堆栈溢出错误之前,计算所用内存的(近似)公式是什么? 许多人回答说“视情况而定”,这是合理的,所以让我们用一个琐碎但具体的例子来删除一些变量: 很容易看出,在我的EclipseIDE中运行它时,的爆炸性增长不到1000(对我来说,这个数字低得出奇)。这个调用深度限制是否可以在不执行的情况下进行估计? 编辑:我忍不住认为Eclipse有

  • 问题内容: 我从星期一开始使用Python进行编程。我很喜欢学习它。但是我一直试图了解如何在tkinter菜单之间切换时避免递归!我确信这是一个非常基本的问题,感谢您宽容我对此主题的无知,但我无法在其他地方找到答案。 我现在正在做的最终是给我错误:RuntimeError:调用Python对象时超出了最大递归深度 这是我目前正在使用的模式。更新:下面的代码现在是完整的隔离副本,再现了我面临的问题!

  • 我对Python很陌生。我写了一个关于返回 x 在排序的重复元素数组 A 中的出现次数的函数: 错误是:运行时错误:超出最大递归深度。有人知道如何解决它吗?

  • 问题内容: 背景:我正在使用最小构造算法构建一个Trie以表示字典。输入列表是430万个utf-8字符串,按字典顺序排序。生成的图是非循环的,最大深度为638个节点。我的脚本的第一行通过将递归限制设置为1100 。 问题:我希望能够将Trie序列化到磁盘上,因此我可以将其加载到内存中,而不必从头开始重建(大约22分钟)。我已经尝试了和,同时使用了文本和二进制协议。每次,我都会得到如下所示的堆栈跟踪

  • 我不明白为什么我会得到这个最大深度错误。iam试图使用bst递归方法在数组中查找数字索引,下面是我的代码 任何人都可以告诉我代码块中发生了什么 错误块: PS C:\Users\admin\Desktop\DSA

  • 问题内容: 这个尾部递归函数: 它工作到了,然后它破裂并吐出了。这只是堆栈溢出吗?有办法解决吗? 问题答案: 是的,可以防止堆栈溢出。Python(或更确切地说,CPython实现)不能优化尾部递归,无限制的递归会导致堆栈溢出。你可以使用来检查递归限制,并使用来更改递归限制,但是这样做很危险-标准限制有些保守,但是Python堆栈框架可能会很大。 Python不是一种功能语言,尾部递归并不是一种特