首页 > 解决方案 > 试图理解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%。

谁能对这种行为给出更多解释。在此处输入图像描述

标签: javacollectionsgarbage-collectiongarbage

解决方案


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

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

在此处输入图像描述

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

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

要获得更快的结果,您可以减小堆大小。


推荐阅读