在 Java 中有一种称为 WeakHashMap 的数据结构,它将弱引用存储为键。每当弱引用从内存中取出时,条目就会从映射中删除。
如果我有一个数据结构,例如堆栈或集合,我在其中存储弱引用,当弱引用从内存中取出时,它们的条目会被自动删除吗?
下面是一个存储弱引用的堆栈示例。
Stack<WeakReference<Object>> objStack = new Stack<WeakReference<Object>>();
在 Java 中有一种称为 WeakHashMap 的数据结构,它将弱引用存储为键。每当弱引用从内存中取出时,条目就会从映射中删除。
如果我有一个数据结构,例如堆栈或集合,我在其中存储弱引用,当弱引用从内存中取出时,它们的条目会被自动删除吗?
下面是一个存储弱引用的堆栈示例。
Stack<WeakReference<Object>> objStack = new Stack<WeakReference<Object>>();
迟到总比不到好。
这不是弱引用的工作方式。-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。