我是 WeakReferences 的新手,所以我只是想了解这一点。我将这段简短的代码放在一起来测试它们的行为。我计划在我正在进行的项目中使用它们,因为我需要临时跟踪对对象的引用。即,我想在集合中引用它们,只要它们不在其他任何地方使用即可。
不过,到目前为止,这个简短的测试代码示例并没有像我希望的那样工作。无论我等多久,weakRef.get() 总是返回值,它永远不会返回 null。
请帮我弄清楚我做错了什么。谢谢。
public static void main(String[] args) throws Exception{
String s = "Hello World!";
WeakReference<String> weakRef = new WeakReference<>(s);
System.out.println("Original1: " + s);
System.out.println("Weak1: " + weakRef.get());
s = null;
Thread.sleep(10000);
Runtime.getRuntime().gc();
int count = 0;
while(weakRef.get() != null){
System.out.println("Not null " + count);
count++;
Thread.sleep(1000);
}
System.out.println("Null");
}
编辑:更新了我的代码示例。我什至尝试手动调用垃圾收集器,最终的 println 仍然输出“Weak2: Hello World!”。
编辑 2:再次更改。将 10 秒的等待移到垃圾收集之前,然后包括循环。循环在垃圾收集后一直运行了 48 秒(在我决定关闭它之前)。
最佳答案
在 Java 中,字符串字面量,例如 "Hello, World!"
是“interned”;也就是说,它们被放入缓存中以供重用。只要加载的类依赖于这些驻留字符串之一,它就不会被垃圾收集器回收,这就是阻止您的 WeakReference
被清除的原因。试试这个:
WeakReference<String> weakRef = new WeakReference<>(new String(s));
当然,不是从源代码中的文字值分配的字符串(例如,从文件内容创建的 String
)将在适当的时间被垃圾回收。您刚刚选择了一个微妙的棘手示例进行测试。
关于Java:WeakReference.get() 不返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35999214/