是否有可能在.NET中创建“隔离岛”场景?

时间:2011-05-18 14:20:44

标签: c# .net garbage-collection

我一直在阅读有关垃圾收集的内容,并开始了解术语“隔离岛”,例如当ObjectA引用ObjectB和ObjectB同时引用ObjectA时。

有人能用C#给我一个例子吗?另外,请您解释一下这是否与“内存泄漏”相同?

4 个答案:

答案 0 :(得分:16)

隔离岛通常是使用参考计数器的GC中的问题。您描述的场景中的ObjectA和ObjectB都具有引用计数1,因此即使也不会收集它,但其他任何内容都无法到达

然而,这不会发生在.NET中,因为.NET的GC使用mark and sweep algorithm。它从根开始并创建一个对象图,因此只有根植的项才能在集合中生存。这意味着没有什么可以是“孤立的”

答案 1 :(得分:7)

<。> .Net中的垃圾收集器不使用引用计数来知道它何时可以收集对象。相反,它构建了一个对象图,其中当前可访问的对象(读取:在范围或全局中)位于图的根部。然后使用图表来查看内存中的每个对象是否都连接到根目录;任何未连接到根的东西都被称为“无根”,可以收集。即使其他对象引用了无根对象,也是如此,只要这些对象也没有根。这样,你所谈论的“隔离岛”不是问题。

答案 2 :(得分:3)

示例来自:When is an object eligible for garbage collection?

class Person {
   public Person firend;
   public static void main(String[] args) {
     Person obj1 = new Person();
     Person obj2 = new Person();
     obj2.firend = obj1;

     obj1 = null;  //Line A
     obj2 = null;  //Line B

     .....
   }
}

在A行执行之后,对象obj2仍然具有对象obj1的引用,并且对象obj2仍然由变量obj2引用。因此,对象obj1不能用于垃圾收集。在B行exectues之后,不再有对象obj2的引用。在对象obj2中仍然存在对象obj1的引用。现在,对象obj1和obj2没有来自根组引用的引用。因此,这两个对象都有资格进行垃圾回收。

答案 3 :(得分:3)

那当然不会在.NET中泄漏。例如:

public class Foo
{
    public Foo Bar { get; set; }
}

...

static void Main()
{
    Foo f1 = new Foo();
    Foo f2 = new Foo();
    f1.Bar = f2;
    f2.Bar = f1;

    // Not actually required so long as nothing in the rest of the method
    // references f1 and f2
    f1 = null;
    f2 = null;

    // The two Foo objects refer to each other, but they're both eligible for
    // garbage collection.
}

在重新计算的系统中,这会泄漏内存 - 在.NET GC中,它不会。当GC运行时,它将找到从已知根可到达的所有对象;任何无法到达的东西都可以被垃圾收集。