28

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

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

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

我主要关心的是使用 Wea​​kReferences(特别是如果使用其中的许多)是否存在与使用标准对象引用不同的性能影响。

4

2 回答 2

21

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

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

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

于 2009-07-08T01:07:42.180 回答
14

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

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

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

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

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

于 2009-07-08T00:51:35.493 回答