ASP.NET: Должен ли я беспокоиться об утечках памяти в определенных ситуациях?[C #] - PullRequest
3 голосов
/ 14 декабря 2010

Меня беспокоит сборка мусора в случае, когда два объекта ссылаются друг на друга ...

public class A
{   public readonly B _b;
    public A()
    {   _b = new B(this);
    }
}

public class B
{   public readonly A _a;
    public B(A objA)
    {   _a = objA;
    }
}

В этом случае третий класс может ссылаться на A ...

public class Foo
{   public A _a = new A(); // A and B are both created here.
    public void Bar()
    {   _a = new A();
    }   // Create a new A (and B)
}

Обычно сборщик мусора располагает объектами, которые больше не имеют активных ссылок.Но в этом случае объекты A и B никогда не теряют все свои активные ссылки, поскольку они всегда ссылаются друг на друга.

Когда объект Foo заменяет текущий AB) нановый AB), сможет ли сборщик мусора очистить старый AB) без запуска бесконечного цикла с круговыми ссылками на объекты?

Thisэто серьезная проблема, потому что это приложение ASP.NET.Эти объекты будут создаваться несколько раз за веб-запрос и могут задерживаться до перезапуска сервера, если сборщик мусора не может их очистить.
Возможные отрицательные результаты:
<< Сбой веб-сервера из-за переполнения ОЗУ. <br><< Сбой веб-сервера из-за бесконечного цикла сбора мусора. </p>

Как .NET обрабатывает сборку мусора в сценарии такого типа?

Ответы [ 4 ]

7 голосов
/ 14 декабря 2010

.NET GC работает путем отслеживания корневых ссылок, таких как статические поля и локальные переменные в области. Он правильно обрабатывает циклы ссылок. например Если A <-> B, но ни на одну из них нет ссылки из корневой ссылки, она собирается.

Давайте рассмотрим, как GC определяет когда он может восстановить память. Когда CLR пытается выделить память и недостаточно памяти в резерве, это выполняет сборку мусора. ГК перечисляет все корневые ссылки, в том числе статические поля и в области видимости локальные переменные при вызове любого потока стек. Это отмечает эти ссылки как достижимы и следуют любым ссылкам эти объекты содержат, маркируя их как также достижимы. Это продолжается процесс, пока он не посетил все достижимые ссылки. Любой без опознавательных знаков объекты не достижимы и, следовательно, мусор. GC уплотняет удалось куча, прибирает ссылки на указать на их новое местоположение в куча, и возвращает управление в CLR. Если достаточно памяти было освобождено, распределение продолжается с использованием этого освобожденная память Если нет, то дополнительные память запрашивается у операционной система.

- от http://msdn.microsoft.com/en-us/magazine/cc163491.aspx

2 голосов
/ 14 декабря 2010

Если A -> B, B -> A и нет других ссылок на A и B, GC достаточно умен, чтобы освободить эти объекты.

В ASP.NET добавлена ​​страховка пула приложений. Многочисленные экземпляры приложения хранятся в памяти и назначаются различным сеансам по мере необходимости. Время от времени, даже в контексте сеанса, IIS решает, что пришло время обновить пул приложений. Когда сеанс заканчивается, IIS обычно закрывает и перезапускает приложение, если оно сталкивается с лимитом памяти для каждого приложения, для пула или общего объема системной памяти. Иногда это даже происходит в середине сеанса; это часто встречается в SOA, где внешний веб-уровень взаимодействует с другим сервером через WCF, и уровень обслуживания может обновляться между вызовами веб-уровнем.

1 голос
/ 14 декабря 2010

Проще говоря:

Когда работает сборщик мусора, он запускается с таких вещей, как регистры памяти и статические поля и тому подобное.Они известны как «Корни».

Оттуда сборщик мусора следует ссылкам из корня на другие экземпляры объектов.Это создает график всех объектов, достижимых из корней.

Если ваши объекты не достижимы из корней, то они считаются не связанными и могут быть удалены сборщиком мусора.

1 голос
/ 14 декабря 2010

Сборщик мусора .NET без проблем очищает циклические ссылки.

Он не считает ссылки на объекты, подобные старому VB6 GC.
Он отслеживает активные объекты, просматривая все объекты в памяти, начиная со специального"корни объекта".

...