8

在 Java 中有一种称为 WeakHashMap 的数据结构,它将弱引用存储为键。每当弱引用从内存中取出时,条目就会从映射中删除。

如果我有一个数据结构,例如堆栈或集合,我在其中存储弱引用,当弱引用从内存中取出时,它们的条目会被自动删除吗?

下面是一个存储弱引用的堆栈示例。

Stack<WeakReference<Object>> objStack = new Stack<WeakReference<Object>>();
4

2 回答 2

2

是的。您所描述的是一般的弱引用属性,而不是WeakHashMap具体的。

API

假设垃圾收集器在某个时间点确定一个对象是弱可达的。那时它将自动清除对该对象的所有弱引用......

于 2012-08-10T21:56:38.127 回答
1

迟到总比不到好。

这不是弱引用的工作方式。-objectWeakReference将永远存在,但它的get()-method 可能会返回原始对象或null(如果原始对象是 GC:ed)。

这意味着您的 Stack 将始终包含一个WeakReference-object。

这是我做的一个详细测试(但是它取决于 JVM 在中间执行 GC,这可能会或可能不会发生在“命令”上 -System.gc()如果没有发生,请尝试添加更多:s):

public static void main(String[] args) {
    // Set up
    Object object = new Object();
    final WeakReference<Object> weakReference = new WeakReference<>(object);
    final Stack<WeakReference<Object>> references = new Stack<>();      
    references.add(weakReference);

    // Before
    System.out.println("Before:");

    references.forEach(r -> {
        System.out.println("Reference: " + r);
        System.out.println("Object: " + r.get());
    });

    // GC
    object = null;

    System.gc();
    System.gc();
    System.gc();

    // After
    System.out.println("After:");
    references.forEach(r -> {
        System.out.println("Reference: " + r);
        System.out.println("Object: " + r.get());
    });
}

输出:

Before:
Reference: java.lang.ref.WeakReference@238e0d81
Object: java.lang.Object@31221be2
After:
Reference: java.lang.ref.WeakReference@238e0d81
Object: null

您最好的方法可能是忽略“弹出”它们后get()返回的条目。null

旁注:我的第一个测试是使用一个从未得到 GC:ed 的字符串对象。这是因为 Java 中的字符串是“内部的”(请参阅​​ 参考资料String.intern()),这意味着有一个隐藏的静态字符串缓存可以重用。字符串永远不会被 GC:ed,除非字符串池已满(或类似的东西......)我认为字符串是唯一具有这种“特殊”特性的 Java 对象,但我建议始终使用自定义对象在 WeakReference 中以确保它得到正确的 GC:ed。

于 2019-08-30T17:25:16.360 回答