Можно ли создать сценарий «Остров изоляции» в .NET? - PullRequest
10 голосов
/ 18 мая 2011

Я читал о сборке мусора и узнал термин «остров изоляции», например, когда ObjectA ссылается на ObjectB и ObjectB одновременно ссылается на ObjectA.

Может кто-нибудь дать мне пример этого в C #? Кроме того, не могли бы вы объяснить, является ли это «утечкой памяти»?

Ответы [ 4 ]

16 голосов
/ 18 мая 2011

Остров изоляции, как правило, является проблемой в GC, которые используют счетчики ссылок. ObjectA и ObjectB в сценарии, который вы описали, поэтому оба имеют счетчик ссылок, равный 1, и поэтому не будут собираться даже , хотя ничто другое не может достичь его .

Однако в .NET этого не происходит, поскольку в .NET GC используется метка и алгоритм развертки . Он начинается с корней и создает граф объектов, поэтому только элементы, укорененные в корне, выживут в коллекции. Это означает, что ничто не может быть «изолированным»

7 голосов
/ 18 мая 2011

Сборщик мусора в .Net не использует подсчет ссылок, чтобы узнать, когда он может собирать объект.Вместо этого он создает граф объектов, в котором объекты, доступные в данный момент (читай: в области видимости или глобально), находятся в корне графа.Затем он использует график, чтобы увидеть, связан ли каждый объект в памяти с корнем;все, что не связано с корнем, называется «нерутированным» и может быть собрано.Это верно даже в том случае, если другие объекты имеют ссылки на некорневый объект, если эти объекты также не являются корневыми.Таким образом, тот «остров изоляции», о котором вы говорите, не является проблемой.

3 голосов
/ 18 мая 2011

Ну, это, конечно, не течет в .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 запускается, он обнаружит, что все объекты достижимы из известных корней; все недоступное может быть собрано мусором.

3 голосов
/ 18 мая 2011

Пример из: Когда объект подходит для сборки мусора?

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 обнаружена, больше нет ссылок на объект obj2.Внутри объекта obj2 все еще есть ссылка на объект obj1.Теперь объект obj1 и obj2 не имеют ссылки из корневого набора ссылок.Поэтому оба объекта пригодны для сборки мусора.

...