【问题标题】:WeakReference implementation in .NET.NET 中的弱引用实现
【发布时间】:2010-11-08 21:23:37
【问题描述】:

我理解并欣赏 System.WeakReference 类在 .NET 框架中的用处,但对实现细节感到好奇。

WeakReference 如何在 .NET 中实现? MSDN 详细讨论了 WeakReference 的用法,但我所看到的关于它如何在幕后工作的细节很少。

CLR 如何在不阻止 GC 的情况下跟踪引用并知道在收集 Target 时将内部句柄清空?它是否需要在 CLR 本身中进行特殊处理?

我主要关心的是使用 Wea​​kReferences(尤其是如果使用其中很多)是否会产生与使用标准对象引用不同的性能影响。

【问题讨论】:

标签: .net reference clr reference-counting


【解决方案1】:

你提到了 MSDN;你已经看过这篇文章了吗?

http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

还可以查看同一作者 (Jeffrey Richter) 的“应用 Microsoft .NET 框架编程”中的第 19 章。这一章是关于垃圾收集的,并且有一节是关于弱引用内部的。

一般来说,如果您在 WeakReferences 中访问大量 Targets,那么性能就会受到影响,因为 WeakRef 在返回目标之前做了一些工作(主要是为了线程安全)。这显然不如直接使用对象引用便宜。另一方面,在存储对大对象的引用时,您会获得一些性能,因为当出现内存问题时,垃圾收集器有更多的选择。

我从来没有尝试量化这种权衡,或者知道这里有任何参考资料。显然,它根据应用程序而有所不同。

【讨论】:

  • +1,感谢您提供的参考资料。仅供参考,我做了更多的研究,并且在 WeakReference 中线程安全的开销令人惊讶地很少 - 主要是必须让 GCHandle 交回对象,这就像取消引用两次,加上几个空检查。
  • 我想我记得几年前看到过,但我真的应该在把它写进答案之前确认它。感谢您注意到这一点,里德。
【解决方案2】:

WeakReference 类将其对象引用移交给 GC 并获得一个句柄。每当您获取引用或检查引用是否存在时,句柄用于向 GC 请求引用。

这意味着 GC 会保留所有弱引用的列表,在收集对象时它必须更新该列表。这也意味着每次使用弱引用都会产生一些开销。

因此,每个弱引用都意味着垃圾收集器需要做更多的工作,但另一方面,每个常规引用​​也一样,即使它更少。当然,在使用大量弱引用时你应该小心一点,但如果你需要它来让内存管理与你的对象一起工作,那应该会超过它导致的小开销。

【讨论】:

  • 我将把它设置为答案,因为它是一个很好的、基本的过程描述。谢谢古法。
猜你喜欢
  • 2011-02-16
  • 2021-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
相关资源
最近更新 更多