如何使堆溢出?

时间:2019-04-03 18:59:06

标签: java

我知道对象引用是在堆栈上创建的,而对象本身是在堆上创建的。在下面的代码中,我尝试通过使用构造函数中的递归来创建大量Main对象来填充堆。但是,我得到了一个OutOfMemoryError

,而不是StackOverflowError
public class Main {
 public Main() {
     new Main();
}

public static void main(String[] args) {
    new Main();
}
}

为什么会这样?

1 个答案:

答案 0 :(得分:0)

使用new创建对象时,它将调用该对象的构造函数。构造函数是一个方法。每次方法调用都将导致创建另一个堆栈框架,每个堆栈框架都将使用可用堆栈空间的一部分。一旦堆栈空间用完,您将得到一个StackOverflowError。无限递归将迅速耗尽可用的堆栈空间。在您的代码中,存在一个竞争,首先要耗尽堆栈空间还是堆空间。但是,在大多数默认限制下,堆栈将比堆小得多。

要导致OutOfMemoryErrorwhile(true)循环内创建许多对象,并确保垃圾回收器无法收集这些对象。例如:

public class MyObject {

    int[] array = new int[1024*256];

    static List<MyObject> myList = new LinkedList<>();

    public static void main(String[] args) throws Exception {
        while(true){
            myList.add(new MyObject());
        }
    }
}