栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

当实际对象被垃圾回收时,WeakHashMap条目中的值如何被垃圾回收?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

当实际对象被垃圾回收时,WeakHashMap条目中的值如何被垃圾回收?

您误会了情况。当

map.values().contains(meta)
或short
map.containsValue(meta)
返回时
false
,并不表示
meta
已被垃圾回收。实际上,您在其中持有对该对象的引用
meta
,甚至将该引用传递给
contains
可能
equals
在其上调用的方法。那么该对象如何被垃圾回收?

该响应仅告诉您映射的键之一与该对象之间没有关联,并且由于唯一的键已被垃圾回收,因此这是正确的答案。或者,您可能只是要求

map.isEmpty()
检查关联的存在。

这是

WeakHashMap
提供的:

基于哈希表的

Map
接口实现,带有 弱键
。当a中的某个条目
WeakHashMap
不再用作其键时,该条目将自动删除。更准确地说,给定键的映射的存在不会阻止该键被垃圾收集器丢弃,即被终结化,终结化和回收。丢弃键后,其条目会从映射中有效删除,因此此类的行为与其他
Map
实现有所不同。

条目的删除不是瞬时的。它依赖于将排队

WeakReference
到a中
ReferenceQueue
,然后在进行下一个查询(例如
containsValue
或)时在内部对其进行轮询
size()
。例如,如果我将您的程序更改为:

Person p = new Person();WeakHashMap<Person, Personmetadata> map = new WeakHashMap<>();Personmetadata meta = new Personmetadata("Geek");map.put(p, meta);WeakReference<?> ref = new WeakReference<>(p);p = null;while(ref.get() != null) System.gc();System.out.println(map.containsValue(meta)? "Value present": "Value gone");

尽管

Person
此时已证明关键实例已被垃圾回收,但它偶尔还是打印“ Value present”
。如上所述,这与地图的内部清理有关,而不是与
Personmetadata
我们始终保持强烈引用的实例有关
meta

使有

Personmetadata
资格进行垃圾回收是完全不同的事情。如前所述,
WeakReference
每当我们调用方法an时,都会进行内部清理。如果我们不这样做,就不会进行清理,因此即使密钥已被垃圾回收,它仍然是一个强大的参考。考虑:

Person p = new Person();WeakHashMap<Person, Personmetadata> map = new WeakHashMap<>();Personmetadata meta = new Personmetadata("Geek");map.put(p, meta);WeakReference<?> personRef = new WeakReference<>(p);WeakReference<?> metaRef = new WeakReference<>(meta);p = null;meta = null;while(personRef.get() != null) System.gc();System.out.println("Person collected");for(int i = 0; metaRef.get() != null && i < 10; i++) {    System.out.println("Personmetadata not collected");    System.gc();    Thread.sleep(1000);}System.out.println("calling a query method on map");System.out.println("map.size() == "+map.size());System.gc();System.out.println("Personmetadata "+(metaRef.get()==null? "collected": "not collected"));

哪个会打印

Person collectedPersonmetadata not collectedPersonmetadata not collectedPersonmetadata not collectedPersonmetadata not collectedPersonmetadata not collectedPersonmetadata not collectedPersonmetadata not collectedPersonmetadata not collectedPersonmetadata not collectedPersonmetadata not collectedcalling a query method on mapmap.size() == 0Personmetadata collected

演示在

WeakHashMap
最终调用该方法之前,该方法如何强烈引用已收集键的值,从而使它有机会执行其内部清理。

WeakHashMap
方法或我们的方法都没有引用它时,最终会收集该值。当我们删除该
meta =null;
语句时,该映射在最后(内部清除之后)仍将为空,但不会收集该值。

重要的是要记住,这些代码示例仅用于演示目的并涉及特定于实现的行为,最值得注意的是,

main
方法通常未优化运行。正式地,如果未使用引用对象,则不需要局部变量来防止垃圾收集,这在优化方法时实际上具有相关性。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/438262.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号