我试图在Java中研究不同的异常并遇到OutOfMemoryError,我想在工作中看到它,所以我编写了以下程序,通过在无限循环中创建它们来创建无限对象。该程序确实进入无限循环,它不会抛出OutOfMemoryError异常。
class Test {
public static void main(String...args) {
while(true) {
Integer i = new Integer();
}
}
}
你走在正确的轨道上。您唯一缺少的是垃圾收集的概念。该程序确实创建了无限的Integer对象,但在第一次迭代之后,在上一次迭代中创建的对象符合GC的条件。
考虑一下:
Integer i;
i = new Integer(); // 1. create new object and make reference variable i refer to it.
i = new Integer(); // 2. create another object and make reference variable i refer to it...there is no way to get to the object created in step1 so obj in step 1 is eligible for GC.
如果你想看到OutOfMemoryError,你需要somhow确保有一种方法来获取在无限循环中创建的对象。所以你可以这样做:
class Test {
public static void main(String...args) {
Vector v = new Vector(); // create a new vector.
while(true) {
v.addElement(new Integer(1)); // create a new Integer and add it to vector.
}
}
}
在这个程序中,Integer对象像以前一样无限创建,但现在我将它们添加到向量中,因此请确保有一种方法可以获取它们并且它们不会成为GC符合条件的。
在你击中i
之前,你的变量OutOfMemoryError
是垃圾收集的,因为它不再被使用了。
获取OutOfMemoryException的最简单方法是创建一个不适合内存的数组:
public class TestOutOfMemoryException { public static void main(String[] args) { final long maxMemory = Runtime.getRuntime().maxMemory(); System.out.println(maxMemory); final byte[] boom = new byte[(int) maxMemory]; } }
变量i
仅限于循环,它不会在每次迭代后存活。因此,在程序耗尽内存之前,它会被垃圾收集。尝试在进入循环之前创建一个ArrayList并将i
的每个实例添加到它:
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
while (true) {
Integer i = new Integer();
list.add(i);
}
}
}
尝试类似的东西
List l = new ArrayList();
int i = 0;
while(true) { l.add(i++); }