java - HashMap 中的强引用
问题描述
我试图理解强引用和弱引用,在 WeakHashMap 的帮助下我们可以轻松实现,但是我们如何在 HashMap 中实现呢?当我使用下面的代码时,String s3 不是垃圾收集,为什么会这样?
HashMap<String,String> wh=new HashMap<String,String>();
String s1=new String("Google");
String s2=new String("Microsoft");
String s3=new String("Apple");
wh.put(s1, "Search Engine");
wh.put(s2, "OS");
wh.put(s3, "Mac");
System.out.println(wh);
//s3=null;
WeakReference<String> wf=new WeakReference<>(s3);
s3=null;
System.gc();
System.out.println(wh);
// Output-{Google=Search Engine, Apple=Mac, Microsoft=OS}
当我对 WeakHashMap 做同样的事情时,它工作得很好。
WeakHashMap<String, String> wh = new WeakHashMap<String, String>();
String s1 = new String("Google");
String s2 = new String("Microsoft");
String s3 = new String("Apple");
wh.put(s1, "Search Engine");
wh.put(s2, "OS");
wh.put(s3, "Mac");
System.out.println(wh);
s3 = null;
System.gc();
System.out.println(wh);
解决方案
这是因为仍然会有一个HashMap
键引用该s3
对象用来引用的字符串:
HashMap<String,String> wh = new HashMap<String,String>();
// s1 and s2 remain the same (omitted for brevity)
String s3 = new String("Apple");
// Here you are adding a Map Entry whose key is referencing `s3` (or more explicitly, the same String `s3` is referencing)
wh.put(s3, "Mac");
// Here you are declaring a `WeakReference` to the same String, but that String is still referenced in a `Map.Entry` key (from above HashMap)
WeakReference<String> wf = new WeakReference<>(s3);
// Nullifying s3 adds nothing as well, as you are only setting the local variable s3 to null (still the same String that s3 used to reference referenced by the Map.Entry key)
s3 = null;
// Calling the Garbage Collector won't collect the String object that s3 used to reference (since there still a hard reference in the Map.Entry referencing it)
System.gc();
// So you will still get the String content (that 's3' used to reference) when you print `wh` since it still has an entry referencing the same String that have not been garbage collected
System.out.println(wh);
请注意,除了您对 s3 的弱引用的混淆假设之外,不能保证 GC 将System.gc()
在 JDK API 中记录的a 上运行:
无法保证此工作将回收任何特定数量的未使用对象,回收任何特定数量的空间,或在任何特定时间(如果有的话)在方法返回之前或永远完成。
推荐阅读
- r - 使用 difftime 和 dplyr 设置函数的参数
- java - 如何在 Java 9+ 中设置默认垃圾收集器?
- python - matplotlib.dates 是否有 AutoMinorLocator 等价物?
- c++ - 访问派生类对象列表的元素会引发“读取访问冲突”异常,而列表由函数填充
- elasticsearch - 在 ElasticSearch 中使用多个字段的匹配来限制搜索结果
- java - /\ 有什么功能?(一个反斜杠和一个正斜杠)
- php - 如何通过在 php 中单击按钮将 AJAX 信息从用户传递给另一个用户?
- angular - 如何根据已验证或未验证将用户重定向到不同的网址
- c# - 如何获取列表框中每行的日期之间的时间?
- javascript - Javascript嵌套解构语法