为什么这个 java 程序总是以内存不足结束



我的java版本如下。

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

我的程序非常简单。代码如下。

import java.util.concurrent.ThreadLocalRandom;
public class Test {
static class DummyObj {
public String t1;
public Integer t2;
public Long t3;
public Double t4;
public DummyObj() {
int i = ThreadLocalRandom.current().nextInt(10000);
t1 = "t1t1t1" + i;
t2 = 222 + i;
t3 = 3333L + i;
t4 = 44444.0 + i;
}
}
void f1() {
for (int i=0; i<100; ++i) {
DummyObj t0 = new DummyObj();
if (8 == ThreadLocalRandom.current().nextLong(1000000))
System.out.println(t0.t3);
}
}
public static void main(String... arg) {
Test t0 = new Test();
while (true) {
t0.f1();
try {
Thread.sleep(2L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};

我运行以下命令来运行这个程序

javac test.java
java -Xmx8m test

程序总是因内存不足错误而崩溃。

有谁知道为什么 gc 无法释放内存?

除此之外,我进行这个实验是为了了解Java垃圾收集器的工作原理(所以这不是某种"生产代码" - 它旨在显示GC"正在做它的工作")。

首先,您正在运行具有 8 MB 内存的 JVM。对于Java应用程序来说,这就像"什么都没有"。

然后你正在高速创建新对象。是的,有一些睡眠,但你的代码仍然只是一直在制造垃圾。如果你的代码的唯一目的是创建垃圾 - 你如何期望任何垃圾收集器跟上它?

这就是重点:垃圾收集不是魔法。它仍然需要时间才能发生。当你结合

  • 从超级少的内存开始
  • 代码除了创建垃圾和睡眠之外什么都不做

您的应用程序迟早会耗尽内存。

正如您声明您"想通过测试学习"GC 的工作原理......这个问题的答案甚至更短:你不能。垃圾回收是高级,复杂的主题。你绝对不能通过编写做这个或那个的小测试用例来"学习"它是如何工作的。现代Java垃圾收集器做着无数不同的事情。请记住:这项技术有20 +年的研究。通过测试观察到的效果不会给你足够的信息来学习任何东西。你就像一个人试图在一个巨大的房间里理解所有的事情 - 同时在外面,试图透过钥匙孔看!

你将不得不在这里咬紧牙关 - 意思是:你将不得不学习文档和教程。从这里开始或直接从SO开始,在这个有很多深入答案的问题上)。

最新更新