尝试通过以下代码了解 GC
public class Test1 {
public static void main(String[] args) {
//HashMap<String,String> newmap = new HashMap<String,String>();
//CleanUpThread t = new CleanUpThread(newmap);
ArrayList<Double> al = new ArrayList<Double>();
//t.start();
while(true){
al.add(Math.random());
try {
Thread.currentThread().sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
由于我在列表中创建随机 double 对象,我预计会发生内存不足错误并且我的堆会被填满。
但我看到我的 GC 正在清理,只有大约 1Mb 的数据保留在幸存者空间中。
以 32MB 堆大小和 GC 占用率设置为 30% 运行 jvm。
最佳答案
首先,您没有出现 OutOfMemoryError,因为您代码中的对象创建速度非常慢(每 200 毫秒)。尝试删除 sleep
代码片段。
其次,如果您的 GC 清理了幸存者空间中的数据,并不意味着 GC 从内存中删除了这些对象。这意味着,GC 将这些对象移到了老年代,因为它们在几次垃圾回收中幸存下来。您可以看到,老年代的大小只会增长,并且那里没有发生垃圾回收。
当你的堆大小将被填满时,GC 将尝试清理对象(你会在 GC 时间图表上看到经常波动),但这种尝试不会成功,因为它不会删除任何对象。随着时间的推移,您将收到 OME。
我认为,如果您删除 sleep
代码片段并等待足够的时间,您将收到 OME。
为了更快地获得结果,您可以减小堆大小。
关于java - 试图理解 java 中的垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56097588/