为什么不使用对象集合重现 OutOfMemoryError?
Why isn't OutOfMemoryError reproduced with a Collection of Object?
我正在尝试使用此代码重现 OutOfMemoryError
:
List<Object> objects = new LinkedList<>();
while (true)
objects.add(new Object());
}
但它实际上从未发生过,我使用了 -Xmx512 并且 JVM 每次只占用大约 497 MB,然后内存就不会被消耗。
我用的是jdk1.8.0_151
谁能帮我弄清楚为什么没有抛出错误?
编译器可能会删除此代码,因为它被认为是死代码并且根本不会执行它。
尝试在循环中 中引入像打印语句这样的副作用。
相当简单(在 IntelliJ IDEA 中执行):
public class Foo {
public static void main(String[] argv) throws IllegalAccessException {
Collection<byte[]> data = new ArrayList<>();
for (;;) {
data.add(new byte[1000]);
}
}
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Foo.main(Foo.java:15)
Process finished with exit code 1
您没有得到 java.lang.OutOfMemoryError
,因为您正在创建非常小的对象 (new Object()
),并且您指定的堆大小非常大。如果您想查看 OOM,则:
- 您使用小对象
new Object()
+ 小堆大小 Xmx64
- 您创建了一些沉重的对象,例如 Calendar (
objects.add(Calendar.getInstance());
) + Xmx512
使用new Object()
+ Xmx512
,需要等待很长时间才会OOM
关于你无法访问的代码错误,我想你已经发现你有括号问题,如果你像下面那样,那么你不会得到那个编译错误,但是如果你在 WHILE 循环之后放置任何语句,那么你会得到那个错误。
while (true){
objects.add(Calendar.getInstance());
System.out.println(objects);
}
我正在尝试使用此代码重现 OutOfMemoryError
:
List<Object> objects = new LinkedList<>();
while (true)
objects.add(new Object());
}
但它实际上从未发生过,我使用了 -Xmx512 并且 JVM 每次只占用大约 497 MB,然后内存就不会被消耗。
我用的是jdk1.8.0_151
谁能帮我弄清楚为什么没有抛出错误?
编译器可能会删除此代码,因为它被认为是死代码并且根本不会执行它。
尝试在循环中 中引入像打印语句这样的副作用。
相当简单(在 IntelliJ IDEA 中执行):
public class Foo {
public static void main(String[] argv) throws IllegalAccessException {
Collection<byte[]> data = new ArrayList<>();
for (;;) {
data.add(new byte[1000]);
}
}
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at Foo.main(Foo.java:15)
Process finished with exit code 1
您没有得到 java.lang.OutOfMemoryError
,因为您正在创建非常小的对象 (new Object()
),并且您指定的堆大小非常大。如果您想查看 OOM,则:
- 您使用小对象
new Object()
+ 小堆大小Xmx64
- 您创建了一些沉重的对象,例如 Calendar (
objects.add(Calendar.getInstance());
) +Xmx512
使用new Object()
+ Xmx512
,需要等待很长时间才会OOM
关于你无法访问的代码错误,我想你已经发现你有括号问题,如果你像下面那样,那么你不会得到那个编译错误,但是如果你在 WHILE 循环之后放置任何语句,那么你会得到那个错误。
while (true){
objects.add(Calendar.getInstance());
System.out.println(objects);
}