在Java中,有一个名为WeakHashMap的数据结构,它将弱引用存储为键。每当弱引用从内存中取出时,该条目将从地图中删除。
如果我有一个数据结构,例如Stack或Set我存储的弱引用,当弱引用从内存中取出时,它们的条目是否会被自动删除?
以下是存储弱引用的Stack的示例。
Stack<WeakReference<Object>> objStack = new Stack<WeakReference<Object>>();
答案 0 :(得分:2)
答案 1 :(得分:1)
迟到总比不到好。
弱引用不是这样工作的。 WeakReference
对象将始终存在,但是其get()
方法可能返回原始对象或null
(如果原始对象是GC:ed)。
这意味着您的堆栈将始终包含一个WeakReference
对象。
这是我进行的详细测试(但是,这取决于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
的条目。
侧面说明:我的第一个测试是使用String对象,它从未使用过GC:ed。这是因为Java中的字符串是“ interned”的(请参见String.intern()
),这意味着有隐藏的静态字符串缓存可以重用。字符串永远不会被GC:ed,除非该字符串池已满(或沿这条线...)。我认为字符串是唯一具有这种“特殊”特征的Java对象,但我建议始终使用定制对象在WeakReference中,以确保其正确获得了GC:ed。