4

我有一个用 c# 实现的二叉树,其方法clear()使根为 null,从而删除了对堆中根节点的引用。这使得堆中的根节点有资格进行垃圾回收。

但是在垃圾收集周期中,只会收集根节点,然后它的两个子节点将在下一个周期中有资格进行垃圾收集,并且需要与树的深度一样多的周期来移除树,或者整个树在堆在一个周期内收集?

4

2 回答 2

3

整个树将被收集,因为 GC 在一个循环中找到了所有无法到达的对象。因为你的树中没有一个节点是可访问的(从某个活动的根),所以应该对整个节点集进行 GC。

这是 GC 工作的一种有效方式 - 但它也是处理自引用数据结构(如双向链表)的好方法(这会导致任何不采用“可访问性”的算法出现问题一些可达的根”考虑在内)。

于 2013-02-11T08:34:45.870 回答
2

实际上,这取决于您的对象存在多长时间。

.NET 使用一种名为“标记和扫描”的算法,此处对其进行了描述。该算法基本上将所有内容标记为删除,除了可以到达的内容。您的对象将在此处的一次迭代中被删除。

然而,天真的标记和扫描将花费大量时间,因为大多数“长寿”对象将在 GC 中存活下来。您拥有的对象越长,GC 标记所有对象所需的时间就越多。这就是 .NET 跟踪对象存活了多少 GC 周期的原因。如果它存活了几次,下一次 GC 将跳过该对象。这些被称为“世代”,并在MSDN上进行了描述。简单地说,一个对象在 GC 循环中存活的次数越多,垃圾收集器访问它以进行删除的频率就越低。

但是,一旦您的结构在某个点被 GC 标记为“未引用”,整个结构将在一次传递中被删除。

于 2013-02-11T08:46:54.920 回答