java - 试图理解 java 中的垃圾收集

标签 java collections garbage-collection garbage

尝试通过以下代码了解 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。

谁能对这种行为给出更多解释。 enter image description here

最佳答案

首先,您没有出现 OutOfMemoryError,因为您代码中的对象创建速度非常慢(每 200 毫秒)。尝试删除 sleep 代码片段。

其次,如果您的 GC 清理了幸存者空间中的数据,并不意味着 GC 从内存中删除了这些对象。这意味着,GC 将这些对象移到了老年代,因为它们在几次垃圾回收中幸存下来。您可以看到,老年代的大小只会增长,并且那里没有发生垃圾回收。

enter image description here

当你的堆大小将被填满时,GC 将尝试清理对象(你会在 GC 时间图表上看到经常波动),但这种尝试不会成功,因为它不会删除任何对象。随着时间的推移,您将收到 OME。

我认为,如果您删除 sleep 代码片段并等待足够的时间,您将收到 OME。

为了更快地获得结果,您可以减小堆大小。

关于java - 试图理解 java 中的垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56097588/

相关文章:

java - ResultSet 到数据库 SQL 查询的不同值的比较

java - 基本类型 map 的 Hibernate 标准

java - 返回 unmodifiableList 是否可以接受,还是应该返回数组?

java - 如何将 enum 与 switch 语句一起使用?

java - JComboBox 中每个项目的多种颜色

java - 如何包装 java.util.Iterator 以更改被迭代对象的类型

java - 识别未被垃圾收集的对象的更好方法?

java - 嵌套循环在 android 中导致大量垃圾收集?

java - WeakReferenced 对象在调用 System.gc() 后未被垃圾回收

JavaScript 中的 Java byteArray 等价物