Java 理解弱引用
我相信我终于理解了WeakReference,我想确定我没有弄错 考虑一个Java 理解弱引用,java,memory-leaks,weak-references,Java,Memory Leaks,Weak References,我相信我终于理解了WeakReference,我想确定我没有弄错 考虑一个Map clientMap,它是名为MyService的Singleton类的private属性,我们使用该类将注册的客户端映射到它们各自的回调 现在考虑下面的代码: // We register a client and it's callback MyService.getInstance().register(client,callback); // .. some code happens .. // At t
Map clientMap
,它是名为MyService
的Singleton
类的private
属性,我们使用该类将注册的客户端映射到它们各自的回调
现在考虑下面的代码:
// We register a client and it's callback
MyService.getInstance().register(client,callback);
// .. some code happens ..
// At this point, we decide client no longer lives anymore
client = null;
到目前为止,即使client
现在指向null
,clientMap
仍然引用了client
以前指向的地址,从而导致内存泄漏
client = null;
MyService.getInstance().unregister(client); // This methods calls Map#remove(Client)
现在我们已经修复了内存泄漏
Map#remove()
,因此这就是WeakReference
的用武之地
通过使用Map clientMap
,引用计数器不会增加,一旦我们设置client=null
它会自动从clientMap
是和否。当所有引用(不包括弱引用)都存在时,对象在下次扫描时可用于垃圾收集。在您的情况下,它不会像预期的那样工作,因为映射仍将包含指向nothing的WeakReference的条目,并且映射到指向nothing的WeakReference,我认为在不迭代所有键/值的情况下无法删除该元素 上一个示例的第二个问题是回调现在也是一个WeakReference,这意味着它可以被垃圾收集,即使它仍在使用中,只要不存在对它的其他引用。听起来不像你想要的
Client client = ...;
Callback callback = ...;
Map< WeakReference< Client >, WeakReference< Callback > > map = ...;
map.put( new WeakReference< Client >( client ),
new WeakReference< Callback >( callback ) );
callback = null;
// Uh oh, callback can now be collected but client is still connected
Client=。。。;
回调=。。。;
Map,WeakReference>Map=。。。;
映射放置(新WeakReference(客户端),
新的WeakReference(Callback));
callback=null;
//哦,现在可以收集回拨,但客户端仍处于连接状态
最好的解决方案是在不再需要时从所有集合中显式删除元素。这消除了对GC的任何依赖,而您从来都不希望依赖GC,并且集合中没有需要稍后清理的悬空条目
另一个解决方案是使用一个。这看起来正是您想要的,它将在回收密钥时处理任何悬空条目。它确实有它自己的陷阱。它不能保证这些条目何时被回收,也不能与循环引用一起使用,因为值仍然是通过强引用引用的。这意味着,如果回调保留对其客户机的引用,它将永远不会被回收,因为回调是强引用,而强引用是对客户机的引用,依此类推
为了澄清为什么WeakHashMap会出现“何时”的问题,WeakHashMap可以随时清理悬空的条目。只要它在没有开发人员干预的情况下完成。这意味着,在不再需要这些值之后,它们仍然可以被强引用。这就是为什么存在这些值的原因。不需要做映射使用WeakHashMap怎么样?WeakHashMap听起来很完美,但我不理解这一点:一旦客户端变为null,插入它的WeakReference现在将返回null值。这是否意味着我必须迭代地图的条目才能删除死亡的WeakReference?“WeakHashMap中的条目将在其密钥不再正常使用时自动删除”不,它将由它自己完成WeakHashMap将管理悬挂的条目本身,这意味着您无需做任何事情来删除它们。同样,文档没有指定何时从映射中删除条目。它只是指定在没有开发人员干预的情况下将其删除。这可能意味着GC可以告诉map释放条目,map会在后台线程上清理自己,或者当开发人员访问map时map会清理。WeakReference,这就像说“嘿,我想要一个对X的引用,但我不想让它一直保持活动状态,如果其他代码不再需要它,就扔掉它,忽略我”请注意,“无限内存使用”与“内存泄漏”不同。如果您的地图包含无限数量的对象,但您仍然可以访问地图实例,则这不是泄漏。它可能最终耗尽可用内存,是的,但不会泄漏。