java 递归和记忆
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13544862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
recursion and memory
提问by Floose
I have a program that passes in huge amounts of data, say 1000 variables, through recursion. The recursion would run to atleast 50 or 60 times. What I'm worried about is, is there a possibility of data getting over- written on the memory locations because there isn't much space, or if the case were that there is no memory, I would get some exception that the program memory has run out (I received no such error)?
我有一个程序通过递归传递大量数据,比如 1000 个变量。递归将运行至少 50 或 60 次。我担心的是,由于没有太多空间,数据是否有可能在内存位置被覆盖,或者如果没有内存,我会得到一些异常,即程序内存已经用完了(我没有收到这样的错误)?
Is there a possibility of getting a wrong solution because the program does not have any more memory and is over-writing on existing locations?
是否有可能得到错误的解决方案,因为程序没有更多的内存并且在现有位置上覆盖?
回答by Raffaele
There are two storage areas involved: the stackand the heap. The stack is where the current stateof a method call is kept (ie local variables and references), and the heap is where objects are stored. The Hotspot documentationsays that on Linux 64-bit each thread has a stack of 1024kB by default. The heap can be made arbitrary big, and today it's in the order of GB.
涉及两个存储区域:堆栈和堆。堆栈是保存方法调用当前状态的地方(即局部变量和引用),而堆是存储对象的地方。Hotspot 文档说在 Linux 64 位上,默认情况下每个线程都有一个 1024kB 的堆栈。堆可以任意变大,今天它的数量级是 GB。
A recursive method uses both the stack and the heap. Which one you run out of first depends on the implementation. As an example, consider a method which needs thousands of integers: if they are declared as local variables, ie:
递归方法同时使用堆栈和堆。首先用完哪个取决于实现。例如,考虑一个需要数千个整数的方法:如果它们被声明为局部变量,即:
public void stackOverflow() {
int a_1;
int a_2;
int a_3;
// ...
int a_10_000_000;
}
your program will crask with a StackOverflowError
. On the other hand, if you organize your integers in an array, like:
你的程序会崩溃StackOverflowError
。另一方面,如果您将整数组织在一个数组中,例如:
public void outOfMemory() {
int[] integers = new int[10 * 1000 * 1000];
}
the heap will be filled soon, and the program will end with an OutOfMemoryError
. In neither case the memory is corrupted or data overridden. However, in both cases the code is wrongand must be fixed somehow - but to tell you howwe'd need to know more about your program.
堆很快就会被填满,程序将以OutOfMemoryError
. 在这两种情况下,内存都已损坏或数据被覆盖。但是,在这两种情况下,代码都是错误的,必须以某种方式修复 - 但要告诉您我们如何需要更多地了解您的程序。
回答by ElderMael
is there a possibility of data getting over- written on the memory locations because there isn't much space
是否有数据在内存位置被覆盖的可能性,因为没有太多空间
Java stores objects in heap space and those values are only reclaimed by the garbage collector. That means that what you are passing are references and not values to your function, that does not consumes memory because you are not copying your variables (but increases memory by increasing stack frames though). If your objects are referenced in a thread stack then there is no way it gets overwritten.
Java 将对象存储在堆空间中,这些值仅由垃圾收集器回收。这意味着您传递的是引用而不是函数的值,它不会消耗内存,因为您没有复制变量(但通过增加堆栈帧来增加内存)。如果您的对象在线程堆栈中被引用,那么它就不会被覆盖。
[...]or if the case were that there is no memory, I would get some exception that the program memory has run out
[...]或者如果没有内存,我会得到一些程序内存已用完的异常
You will get an Asynchronous exception(OutOfMemoryError) in case of the JVM depleted its memory but here the only exception you would get is a StackOverflowErrorif your recursion function calls itself a huge number of times.
如果JVM 耗尽其内存,您将收到一个异步异常( OutOfMemoryError),但如果您的递归函数多次调用自身,您将获得的唯一异常是StackOverflowError。
回答by Haile
There's no chance of getting wrong results: in case of a stackoverflow your program will terminateprematurely with a StackOverflowError.
没有机会得到错误的结果:在 stackoverflow 的情况下,您的程序将因StackOverflowError过早终止。
The memory locations where you store the data cannot be overwritten by anything else.
存储数据的内存位置不能被其他任何东西覆盖。
回答by Jatin
Java or even for that matter C, your program memory will never change the state of unrelated memory.
Java 甚至 C,你的程序内存永远不会改变无关内存的状态。
Though JVM doesn't support tail recursion. So at max you shall get StackOverFlowErrorwhen there is no more space available. You shouldn't worry about data corruption, but rather see if the recursion stack is just too high (say above 2000). Work on it if so
虽然JVM不支持尾递归。因此,当没有更多可用空间时,您将获得最大的StackOverFlowError。您不应该担心数据损坏,而应该查看递归堆栈是否太高(比如 2000 以上)。如果是这样的话
回答by Mukul Goel
There could be two cases
可能有两种情况
Enough memory, recursion completes and you get ressult.
Not mough memory amd get StackOverFlowError and program exits
足够的内存,递归完成,你得到结果。
内存不足 amd get StackOverFlowError 和程序退出
You will not have wrong results because of memory overwriting that does not happen
你不会因为不会发生的内存覆盖而得到错误的结果