0

尝试了所有垃圾收集器,一百万种不同的设置组合。但结果总是一样的——OutOfMemoryError。

谁能告诉哪个垃圾收集器能够及时删除软引用引用的对象

下面的示例模拟器代码

package com;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

class SoftReferenceCollector {

    private static class Data {
        public long[] l = new long[100];
    }

    private List<SoftReference<Data>> list = new ArrayList<>();

    public void startFillCollection(int durationInSec) {
        long i = 0;

        long start = System.currentTimeMillis();
        long end = start + durationInSec * 1000;
        while (System.currentTimeMillis() < end) {
            list.add(new SoftReference<>(new Data()));
            ++i;
            if (i % 10000 == 0) {
                sleep(1);
                if (i % 1_000_000 == 0)
                    sleep(1000);
            }
        }
    }

    private void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException ignored) {
        }
    }
}


public class Main6 {
    public static void main(String[] args) {
        SoftReferenceCollector softReferenceCollector = new SoftReferenceCollector();
        softReferenceCollector.startFillCollection(11240);

    }
}

4

1 回答 1

1

Referents(由 引用的对象SoftReference)在抛出 OOO 异常之前被 GC 清除。

但是没有被垃圾收集的是SoftReference对象本身。它们也是对象,它们消耗堆内存。它们都被列表保存在内存中。GC 只清除它们指向的对象,即referent.

使用-XX:+HeapDumpOnOutOfMemoryError. 此标志将在 OOO 之前转储堆,以便您稍后对其进行分析。您可以使用 Eclipse 内存分析器。

您还可以尝试-XX:+PrintReferenceGC使用 flag 来打印一些有关 gc 周期所用时间的信息,方法是清理这些引用。

于 2022-01-15T20:52:28.690 回答