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

3

可能是重复问题:
弱引用

这个东西有什么用?

它似乎是一种创建对象的方式,让GC可以早期收集它,如果它被早期收集了,我应该只是重新创建它。这听起来像缓存,但其他StackOverflow的问题说这是一个糟糕的缓存策略,因为实际上GC会非常迅速地回收你的对象,( 另一个问题说弱引用不适合做缓存) 类似于使用ASP.NET的Cache并将其设置为非常低的缓存驱逐时间限制。

背景:我最近在阅读TraceSource的CLR代码。在构造函数中,第一件事就是将WeakReference(this)添加到静态字典中。奇怪的是,它只在Refresh方法中使用,当TraceSource重新读取弱引用字典中每个TraceSource的配置文件时,但仅在它尚未被GC回收时使用。另外一个 StackOverflow问题表明这会导致内存泄漏

因此,我一直在阅读有关WeakReferences的文章,越来越感到困惑。


http://weblogs.java.net/blog/2006/05/04/understanding-weak-references - DarthVader
2
@DarthVader 我不确定JVM的行为是否能代表CLR的行为。 - MatthewMartin
3个回答

6
WeakReference经常用于实现弱事件。事件处理程序是内存泄漏的常见原因,特别是当您拥有一个长期存在的服务,并且多个实例订阅事件时。如果这些实例未注销其事件处理程序(因为开发人员没有意识到它很重要或者通常由于异常情况未触发正常清理),则残留的引用会使实例无法被收集。
另一个好的例子是,如果您想将附加数据与现有实例关联起来。例如,您可能有一个ExtraWidgetInfo,您想将其与第三方Widget关联起来。创建关联的一种方法是使用Dictionary。问题在于,现在所有的Widgets都由Dictionary本身保持活动状态,即使它们不再在其他任何地方使用。使用WeakReference进行Widget引用可以避免相关数据使Widgets超过其预期的过期时间而保持活动状态。

3
一个缓存就是一个好例子。如果在缓存中使用弱引用,那么没有被请求的项目可以被垃圾回收以回收内存。
简而言之:任何方便检索但如果您不需要则不是关键的东西。

1

这对缓存来说绝不是好事,因为垃圾回收器会在运行时清理所有当前未引用的缓存项。它不会等待内存压力或其他情况。它也不允许缓存增长。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接