2009-11-28 57 views
8

当WeakReference.Target引用的目标对象已被垃圾收集时,WeakReference会发生什么? WeakRerence是否存活并保持存在? 我问的原因是我有一个WeakReferences列表存储在列表中。在运行期间,新的WeakReferences会不断添加到该列表中。现在,当目标对象死亡时,我是否必须自己清理废弃的WeakReference? 如果是这样,是否有一个聪明的伎俩,我可以做到这一点?当WeakReference被放弃时我能得到通知吗?或者我必须引入一个频繁循环访问该列表的计时器,以查看是否可以从该列表中删除任何WeakReference实例。WeakReference.Gar的GC之后的WeakReference会发生什么变化。目标

+0

顺便说一句,在问题的措辞上做得很好,我觉得很清楚问题是什么,尽管我几乎没有使用.net的经验。 – 2009-11-28 21:09:08

回答

12

这是弱引用的常见问题。引用本身保持活着状态,因为它有正常的指针。正如你所建议的那样,你需要不时进行一些“手动垃圾收集”。请注意,由于其他原因,当您遍历列表时,您可能会清除存根。根据列表的使用模式,这个“在旁边”的垃圾回收可能就足够了。

不要“频繁”循环列表中的唯一目的来清理它!每个死存根只会浪费几个字的记忆。如果清单不经常使用,清理它的计算成本往往是不合理的,如果频繁使用清单,就会按照上面的建议清理自己。

这是另一个垃圾收集系统,但问题是如此相似,你可能有兴趣this article,如果你能得到它。

+0

如果不按索引访问列表,则最好的策略可能是在添加项目时清除它,如果在最后清除和最后一个清除(使用GC计数器)之间添加的项目数量超过了某个特定项目列表大小的一小部分。重要的不是所有的垃圾都被清理干净,而是不符合立即收集条件的垃圾数量仍然有限。顺便说一下,WeakReferences的成本不仅仅是“几个字”。它们并不昂贵,但即使是一百万未使用的弱资源也可能会扼杀一个项目。 – supercat 2011-12-12 14:29:20

6

由于您对WeakReference对象有强烈的参考,因此它不会得到GC'ed。这也是通过设计,因为它的目的是仍然可以使用WeakReference来发现目标已经被GC化了。

所以是的,你必须去计时器的方式。

加:你也可以看看Garbage Collection Notifications

+1

+1,但是我会提醒您不要使用GC通知,因为它们会禁用GC的某些较新(良好)功能。 – user7116 2009-11-30 21:25:59

1

预期用法是使用WeakReferences注册ReferenceQueue。收集目标时,引用被添加到队列中。您可以轮询或等待队列,并从列表中删除WeakReference对象。

+2

你确定这个机制是.NET吗?我认为你指的是Java ... – bitbonk 2010-12-14 09:21:12

+0

哦,对不起,我有一点盲注。我不使用任何.NET,所以当类有这样完全相同的名称时会感到困惑。 – OrangeDog 2010-12-14 10:55:06

相关问题