0

我即将开始使用第 3 方闭源库来加载一堆数据,并想检查它的速度以及加载一个“集”数据需要多少内存。我编写了这个简单的工具来调用数据加载来计时,并使用 YourKit 快速查看内存使用情况并深入研究 CPU 时间。

我在 Windows 7 上运行它,在没有 VM 参数的 JDK8 上使用 Eclipse。

public static void main(String[] args){
    long start = System.currentTimeMillis();

    // There are a few more calls involved, but not much
    BlackBoxDataProvider bd = new BlackBoxDataProvider("c:\\thedata");
    BlackBoxData = bd.loadTheData();
    System.out.println(System.currentTimeMillis() - start + "ms");

    // Keep the application alive so I can have a quick look at memory usage
    while(true) {
        Thread.sleep(1000);
    }
}

这是加载完成后 YourKit 的内存快照:

在此处输入图像描述

然后我使用 YourKit 来“强制”垃圾收集,这发生了:

在此处输入图像描述

显然这不是现实生活中的场景,因为我被困在 main 方法中,在主线程上,所以我的一些引用不会被清理,但我不知道为什么内存分配会不断增加。

每次我单击“强制系统 GC”时,分配都会增加。在它停止增加之前,我达到了 11.9GB。

在此处输入图像描述

为什么会这样?

4

1 回答 1

0

System.gc() 将在所有对象被扫描一次后返回。如果将实现 finalize() 方法的对象添加到队列中,以便稍后清理。这意味着这些对象还不能被清理(不是保存它们的队列节点),即触发 GC 的行为会暂时增加内存消耗。这就是您的情况可能发生的情况。

简而言之,并不是所有的物体都可以在一个周期内清理干净。

于 2018-09-18T15:02:23.377 回答