11

:有没有办法找出一个对象是否有任何“强引用”?


Raymond Chen 暗示可能有一个解决方案

您想知道引用计数是零还是非零。为此,请使用弱引用。

笔记

  • 我对对象有一个“弱引用”(使用Wea​​kReference)。如果我有一个强引用 ,答案将立即是:“是的。你对这个对象有一个强引用。”
  • 垃圾收集器不提供任何答案
  • IsAlive 属性只能告诉您是否已收集对象。如果有强烈的引用,则不是。(没有引用的对象可能会被回收 - GC 还没有解决它)
  • .NET 中的对象不被引用计数
  • 并非所有对象都必须实现IDisposable接口
  • 并非所有物品都是我的

代码示例

此代码示例演示了依赖强制垃圾回收和 WeakReference 的IsAlive属性来确定对象是否有任何未完成的引用的问题。

WeakReference m_wr = null;

...

for (int i = 0; i < 1000000; i++)
{
   Pig p = new Pig();
   m_wr = new WeakReference(p);
}

...

GC.Collect();
if (m_wr.IsAlive)
   Environment.FailFast("All objects should have been collected by now");
4

3 回答 3

11

不,不是不使用调试器 API。

正如你所说,对象不被引用计数......所以找出的唯一方法是爬取堆,这通常只是作为垃圾收集的一部分发生。

请注意,即使在没有“正常”强引用之后,该对象也可以作为终结器的一部分复活 - 如果终结器队列具有终结器,则实际上终结器队列具有对它的引用。无论如何,在那种情况下,您可能不希望将该对象包含为“无引用”。

于 2010-08-12T17:16:23.803 回答
3

您应该阅读 Raymond Chen关于昨天的参考计数的帖子。在那之后 - 你应该决定这是否是你真正需要做的事情以及为什么。然后回来告诉我们为什么。

嗯,看来你已经阅读了这篇文章 - 吸收了一些小细节并错过了重点。


我想知道在数据库连接上调用 Dispose 是否安全。

阅读文档。 Dispose调用关闭。 Close可以随意调用。

一个应用程序可以多次调用 Close。不会产生异常。

于 2010-08-12T17:21:44.480 回答
3

打电话GC.Collect()再查。如果是(即,在调用GC.Collect后尚未收集),则某处存在强引用。WeakReference.IsAlivetrue

于 2010-08-12T17:22:09.673 回答