我相信我终于明白了WeakReference
我想确保我没有弄错。
考虑 Map<Client,Callback> clientMap
那是 private
Singleton
的属性类名为 MyService
我们用它来将注册的客户端映射到它们各自的回调。
现在考虑以下代码:
// 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
stills 引用了地址 client
之前指向,导致内存泄漏。
- 我说得对吗?
如果问题 1 为"is",则继续:我们决定为了防止内存泄漏,我们也应该从客户端映射中删除该对象:
client = null;
MyService.getInstance().unregister(client); // This methods calls Map#remove(Client)
现在我们已经修复了内存泄漏。
- 我的说法仍然正确吗?
如果问题 2 为"is":由于一些无法解释的问题,我们无法真正调用 Map#remove()
这就是 WeakReference
进来。
通过使用 Map<WeakReference<Client>, WeakReference<Callback>> clientMap
,引用计数器不会增加,一旦我们设置client = null;
它会自动从 clientMap
中删除它
- 我仍然是正确的吗?
最佳答案
这就是为什么 WeakHashMap存在。不需要做 Map
现在,真正的 WeakReference 不会阻止垃圾收集器清理它指向的内存。何时发生取决于虚拟机。通常,它会很快清理它,但在负载下它会让它闲逛,直到它绝对必须释放内存。这是垃圾收集器清理内存时所做的最后一件事(如果我没记错的话)。
以这种方式注册回调要小心,因为通常大多数回调都是注册后忘记的,就像忘记引用一样,因此,只有一件事持有对回调的引用,即弱引用。它几乎会立即被 GC 处理,而不会给您回电。因此,如果您这样做,请确保在其他地方保留回调。
关于java - 了解弱引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25314989/