何时在C#中使用WeakReference(如果不是用于缓存)?

时间:2012-10-17 21:15:33

标签: c# weak-references

  

可能重复:
  Weak references

这是为了什么?

这似乎是一种创建GC可以提前收集的对象的方法,如果它早期收集,我应该重新创建它。这听起来像缓存,但其他StackOverflow questions say that this is a lousy cache strategy because the GC in practice will GC your object very eager and fast,(another Q that says weakreference make poor caches)有点像使用ASP.NET的缓存并将其设置为非常低的缓存逐出时间限制。

背景:我最近正在阅读TraceSource的CLR代码。在构造函数中,第一件事就是将WeakReference(this)添加到静态字典中。奇怪的是,当TraceSource重新读取弱引用字典中每个TraceSource的配置文件时,它只在Refresh方法中使用过,但前提是它还没有GC过。另一个StackOverflow question indicates this causes memory leaks

所以我从那时起就开始阅读WeakReferences,并且越来越困惑。

3 个答案:

答案 0 :(得分:6)

WeakReference通常用于实现Weak Events。事件处理程序是内存泄漏的常见原因,尤其是当您拥有包含多个实例订阅的事件的长期服务时。如果这些实例无法注销其事件处理程序(因为开发人员没有意识到它很重要或者通常由于异常情况不会触发正常清理),那么延迟引用会阻止实例被收集。

另一个好例子是,如果要将其他数据与现有实例相关联。例如,您可能有一个要与第三方窗口小部件关联的ExtraWidgetInfo。创建关联的一种方法是使用Dictionary。问题是现在所有的小部件都被字典本身保留了下来,即使它们不再在其他任何地方使用过。对Widget引用使用WeakReference可以防止关联数据使Widgets保持活动超过预期的到期时间。

答案 1 :(得分:3)

缓存就是一个很好的例子。如果在缓存中使用弱引用,则可以对未请求的项进行垃圾回收以回收内存。

简而言之:任何方便撤退的东西,但如果不这样做则不重要。

答案 2 :(得分:1)

当然不适合缓存,因为GC会在运行时清除所有当前未引用的缓存项。它不等待内存压力或其他什么。它不允许缓存增长。