由于嵌套构造函数调用,我有以下代码及其抛出StackOverflowException,并且我知道只有在构造函数成功运行时才会分配内存。
package interview;
public class StackOverflow {
int i;
StackOverflow()
{
System.out.println(" i= "+i);
System.out.println("in Constructor");
StackOverflow sOf = new StackOverflow();
sOf.i=5;
System.out.println(" i= "+i);
}
public static void main(String[] args) {
System.out.println("in main");
StackOverflow s = new StackOverflow();
s.i=10;
System.out.println(" i= "+s.i);
}
}
所以我怀疑这是'i'的价值发生了什么?它是存储在堆栈还是堆中的某个地方? 在这种情况下,上面的代码可以抛出以下异常?
OutOfMemoryException异常
答案 0 :(得分:2)
OutOfMemoryError:当Java虚拟机由于内存不足而无法分配对象时抛出,垃圾收集器不再提供更多内存。
StackOverflowError:当发生堆栈溢出时抛出,因为应用程序过于冗长。
在哪种情况下它可以抛出OutOfMemoryError?
你的构造函数递归地调用自己进入更深层, 堆栈在JVM内存不足之前溢出。
而不是递归使用for
循环来创建太多对象。您
也许可以看到OutOfMemoryError
。
我的问题是i的值发生了什么(它正在获取存储的堆或堆栈):
Java虚拟机堆栈类似于a的堆栈 传统语言如C:它包含局部变量和部分 结果,并在方法调用和返回中起作用。
由于堆是对象的存储空间,而i
是您的对象的字段成员
StackOverflow
类,它存储在Heap
答案 1 :(得分:1)
启动JVM时,会从操作系统为其分配一些内存。 jvm使用这个内存来处理它的purpuses。 JVM以多种方式使用此内存 - 如堆栈和堆。
每当调用一个方法时,该方法中的参数,返回值和其他局部变量等数据都保存在堆栈中。调用该方法时会创建此堆栈,并在方法完成执行时销毁该堆栈。如果你继续从一个方法调用一个方法,那么就会出现一些瓶颈,它将显示一个StackOverFlowError。但是在堆的情况下--JVM从这个堆中为新对象分配内存。如果您有对象的引用,并且堆中剩余的可用空间非常少,它将显示OutOfMemoryError。
答案 2 :(得分:0)
启动JVM时,您可以定义可用于处理的RAM量。 JVM将其划分为某些内存位置以用于其处理目的,其中两个是Stack
& Heap
OutOfMemoryError
与Heap有关。如果在memeory中有大对象(或)引用的对象,那么您将看到OutofMemoryError
。
StackOverflowError
与堆栈有关。所有局部变量和方法调用相关数据都将在堆栈中。对于每个方法调用,将创建一个堆栈帧,并且本地以及与方法调用相关的数据将被放置在堆栈帧内。方法执行完成后,将删除堆栈帧。重现这一点的一种方法是,对于方法调用有无限循环,你会看到stackoverflow
错误,因为堆栈帧将填充每个调用的方法数据,但它不会被释放(删除)。 / p>
在你的情况下,你正在调用导致堆栈溢出而不是堆的构造函数,因此得到StackOverflowError
而不是OutOfMemoryError
。
StackOverflow()
{
StackOverflow sOf = new StackOverflow(); //causing Stack to overflow.**
}
i
的值始终为0
,即默认值。
请参阅this。
答案 3 :(得分:0)
无论何时调用另一个函数内的函数,第二个函数都位于堆栈的顶部。因为你已经对构造函数进行了递归调用,所以由于你的新构造函数,它会不断增加你的Stack大小。如果没有空间在主堆栈中创建新的构造函数条目, JVM 将抛出StackOverflowException
。
对于OutofMemoryException
,您只需要创建尽可能多的对象,以便堆中没有剩余空间。
Class variables and Objects are created in Heap and function calls, and local variables are maintained in Stack.
i
是class variable
,因此会存储在Heap
中。并且由于它在声明时未定义,因此将获得int的默认值,即0
。您的构造函数永远不会到达您将值5
赋给i
的行。因此,它始终具有值0
。