java - 了解弱引用

标签 java memory-leaks weak-references

我相信我终于明白了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现在指向nullclientMap stills 引用了地址 client之前指向,导致内存泄漏。

  1. 我说得对吗?

如果问题 1 为"is",则继续:我们决定为了防止内存泄漏,我们也应该从客户端映射中删除该对象:

client = null;
MyService.getInstance().unregister(client); // This methods calls Map#remove(Client)

现在我们已经修复了内存泄漏。

  1. 我的说法仍然正确吗?

如果问题 2 为"is":由于一些无法解释的问题,我们无法真正调用 Map#remove()这就是 WeakReference进来。

通过使用 Map<WeakReference<Client>, WeakReference<Callback>> clientMap ,引用计数器不会增加,一旦我们设置client = null;它会自动从 clientMap 中删除它

  1. 我仍然是正确的吗?

最佳答案

这就是为什么 WeakHashMap存在。不需要做 Map,>。只需使用 Wea​​kHashMap,它就会自行清理。在 WeakHashMap 中,键是弱保留的,这很好,但值是硬引用。这很好,因为当键被回收时,该值将被删除。阅读文档以了解警告,了解为什么这很重要。

现在,真正的 WeakReference 不会阻止垃圾收集器清理它指向的内存。何时发生取决于虚拟机。通常,它会很快清理它,但在负载下它会让它闲逛,直到它绝对必须释放内存。这是垃圾收集器清理内存时所做的最后一件事(如果我没记错的话)。

以这种方式注册回调要小心,因为通常大多数回调都是注册后忘记的,就像忘记引用一样,因此,只有一件事持有对回调的引用,即弱引用。它几乎会立即被 GC 处理,而不会给您回电。因此,如果您这样做,请确保在其他地方保留回调。

关于java - 了解弱引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25314989/

相关文章:

java - PriorityQueue 有相同优先级的对象

java - 通知后接着另一个通知

ios - CoreImage 的内存泄漏

delphi - 如何使用 fastMM 追踪棘手的内存泄漏?

objective-c - 如何在 clang 中使用 __weak 引用?

python - weakref (WeakKeyDictionary) 来框架 (FrameType) 对象

java - Android - 如何将 txt 文件上传到网站?

java - Cucumber Java - 如何在新步骤中使用步骤返回的参数?

javascript - 处理 svg <image> 时的内存管理

c# - C# 闭包对垃圾收集器的奇怪影响