繁体   English   中英

Java:递归构造函数调用和stackoverflow错误

[英]Java : recursive constructor call and stackoverflow error

请帮忙理解为什么以下代码

public class HeapQn1 {

    /**
     * @param args
     */
    public HeapQn1() {
        new HeapQn1();
    }

    static HeapQn1 n = new HeapQn1();

    public static void main(String[] args) {

    }

}

结果是

java.lang.StackOverflowError
    at com.rg.test.interview.HeapQn1.<init>(HeapQn1.java:8)
    at com.rg.test.interview.HeapQn1.<init>(HeapQn1.java:9)
    ...

根据我的理解,对象的内存分配发生在堆内存中,我期待OutOfMemoryError,因为在某些时候堆内存将因为重复的对象创建而已满。

在研究中,我发现java构造函数被认为是一个方法,并解释了StackOverflowError,直到我读到以下线程。

什么时候在java中调用构造函数?

这说

3. The object is fully constructed/created when the constructor returns.

从我可以收集的,构造函数是一个方法,因为堆内存比堆栈内存大得多,递归构造函数调用导致StackOverflowError。 它是否正确 ?

由于给定代码中的对象不会被完全创建,构造函数的堆栈帧分配实际上会发生吗?

--edit--对于指出的重复项,我确实理解StackoverflowError是什么。 我在问题中提到过“在研究中,我发现java构造函数被认为是一种方法,它解释了StackOverflowError”。 我的问题是要理解构造函数是否像其他方法一样获取堆栈帧,因为在构造函数返回之前对象创建尚未完成。 希望这澄清一下。

每当调用构造函数时,其return address被压入堆栈 由于堆栈是有限的并且小于堆内存,因此会出现类似StackOverflowError而不是OutOfMemoryError

构造函数是一个方法,由于堆内存比堆栈内存大得多,因此递归构造函数调用导致StackOverflowError。 它是否正确 ?

是的,你的疯狂猜测是完全正确的。 干杯!

构造函数是一种方法,也就是函数。 每次调用它时,都会将一块内存分配给堆栈 ,以存储函数的变量。

您的代码无限制地创建对构造函数的调用,将内存分配给堆栈直到内存完成。

您正在获取StackOverflowError而不是OutOfMemoryError ,因为专用于堆栈的内存量小于专用于堆的内存量。

编辑:我已经使用您的代码做了一些测试。 我已经指定了8M( -Xms8M -Xmx8M )的堆内存空间和100M( -Xss100M )的堆栈内存空间。 计算结果始终是错误StackOverflowError

然后,这可能意味着在这种情况下没有为堆分配内存 正如你在问题中所述:

构造函数返回时,对象是完全构造/创建的。

你是对的:堆栈比堆小得多,并且不会完全创建任何对象。

基本上你所说的是正确的,堆栈空间在堆空间之前耗尽。

根据java,所有引用变量都存储在堆栈内存空间中,堆栈内存空间小于堆空间,这就是我们得到的堆栈空间溢出异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM