9

我有一个程序通过递归传递大量数据,比如 1000 个变量。递归将运行至少 50 或 60 次。我担心的是,是否有可能因为没有太多空间而在内存位置上覆盖数据,或者如果没有内存,我会得到程序内存的一些异常已经用完了(我没有收到这样的错误)?

是否有可能因为程序没有更多内存并且在现有位置上覆盖而得到错误的解决方案?

4

5 回答 5

23

涉及两个存储区域:堆栈和堆。栈是保存方法调用的当前状态(即局部变量和引用)的地方,而堆是存储对象的地方。Hotspot 文档说,在 Linux 64 位上,默认情况下每个线程都有一个 1024kB 的堆栈。堆可以任意大,今天是GB的顺序。

递归方法同时使用堆栈和堆。您首先用完哪个取决于实施。例如,考虑一个需要数千个整数的方法:如果它们被声明为局部变量,即:

public void stackOverflow() {
  int a_1;
  int a_2;
  int a_3;
  // ...
  int a_10_000_000;
}

您的程序将使用StackOverflowError. 另一方面,如果您将整数组织在一个数组中,例如:

public void outOfMemory() {
  int[] integers = new int[10 * 1000 * 1000];
} 

堆很快就会被填满,程序将以OutOfMemoryError. 在这两种情况下,内存都已损坏或数据被覆盖。然而,在这两种情况下,代码都是错误的,必须以某种方式修复——但要告诉你我们需要如何更多地了解你的程序。

于 2012-11-24T20:30:00.210 回答
5

是否有可能因为没有太多空间而在内存位置上覆盖数据

Java 将对象存储在堆空间中,这些值仅由垃圾收集器回收。这意味着您传递的是引用而不是函数的值,这不会消耗内存,因为您没有复制变量(但通过增加堆栈帧来增加内存)。如果您的对象在线程堆栈中被引用,那么它就不会被覆盖。

[...]或者如果情况是没有内存,我会得到一些程序内存已用完的异常

如果 JVM 耗尽了它的内存,你会得到一个异步异常( OutOfMemoryError ),但是如果你的递归函数大量调用自身,你会得到的唯一异常是StackOverflowError 。

于 2012-11-24T19:51:37.270 回答
2

没有机会得到错误的结果:如果发生 stackoverflow,您的程序将因StackOverflowError过早终止

存储数据的内存位置不能被其他任何东西覆盖。

于 2012-11-24T19:43:25.150 回答
1

Java 甚至 C 语言,你的程序内存永远不会改变无关内存的状态。

虽然 JVM 不支持尾递归。因此,当没有更多可用空间时,您最多会收到StackOverFlowError 。你不应该担心数据损坏,而是看看递归堆栈是否太高(比如高于 2000)。如果是这样,请继续努力

于 2012-11-24T19:46:00.710 回答
1

可能有两种情况

  1. 足够的内存,递归完成,你得到结果。

  2. 没有足够的内存并得到 StackOverFlowError 和程序退出

由于不会发生内存覆盖,您不会得到错误的结果

于 2012-11-24T19:49:04.893 回答