java - 试图理解java中的垃圾收集
问题描述
试图用下面的代码来理解 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();
}
}
}
}
由于正在将随机双对象创建到列表中,因此我预计会发生内存不足错误并且我的堆会被填满。
但我看到我的 GC 正在清理,只有约 1Mb 的数据留在幸存者空间中。
运行 jvm,堆大小为 32MB,GC 占用百分比设置为 30%。
解决方案
首先,您没有出现 OutOfMemoryError,因为您的代码中的对象创建速度非常慢(每 200 毫秒)。尝试删除sleep
代码片段。
其次,如果你的 GC 清理了幸存者空间中的数据,并不意味着 GC 会从内存中删除这些对象。这意味着,GC 将这些对象移到了老年代,因为它们在几次垃圾回收中幸存下来。您可以看到,老年代的大小只会增长,并且没有发生垃圾收集。
当您的堆大小将被填满时,GC 会尝试清理对象(您会在 GC 时间图上看到经常波动的情况),但此尝试将不成功,因为它不会删除任何对象。随着时间的推移,您将收到 OME。
我认为,如果您删除sleep
代码片段并等待足够的时间,您将收到 OME。
要获得更快的结果,您可以减小堆大小。
推荐阅读
- python - python import * from subdirectory不起作用
- ruby-on-rails - Rails webpacker 无法编译 Vue.js 核心方法
- vue.js - v-for 具有可变数量的内容块
- php - WP 如何在一个类别的管理面板中显示一个包含该类别所有已分配帖子列表的字段?
- flutter - 仅在 Android 上方向更改时 Flutter 应用程序重新启动
- python - 类别预测阈值
- python - 隔离数据事件的最佳方法?
- math - 可被数组的所有元素整除的最小完全平方(大数)
- android - Android AnimatedVectorDrawable 在不同的 API 上有不同的行为
- asp.net - 实现 Azure AD 的协议