Удаление объектов в .Net - PullRequest
1 голос
/ 14 июля 2011

Если у меня есть следующие классы:

Class MainClass
{
   private OtherClass1;
   MainClass()
   {
      OtherClass1 = new OtherClass1();
   }

   void dispose()
   {
      OtherClass1 = null;
   }
}

class OtherClass1
{
   private OtherClass2;
   OtherClass1()
   {
      OtherClass2 = new OtherClass2();
   }
}

class OtherClass2
{
}

Если я установил MainClass и позже вызову метод dispose, получит ли OtherClass1 сборщик мусора (позже)? Или я должен сначала очистить ссылку на OtherClass2?

Ответы [ 5 ]

6 голосов
/ 14 июля 2011

Объект будет собирать мусор, если у него нет ссылок, или ссылки, которые он имеет, взяты из объектов, которые сами не имеют ссылок (и т. Д.).

Способ визуализации - сборщик мусора будет проходить по графу ссылок на объекты, следуя всем ссылкам на объекты, отмечая те, к которым он попадает (все еще ссылаясь откуда-то). Любые, кого он не получает, имеют право на сборку мусора, как если бы он не дошел до них, тогда их невозможно использовать.

Подробную информацию см. Здесь (в частности, «Алгоритм сбора мусора»): http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

Так что да, это будет иметь право быть GC'd.


Кроме того, если у вас есть метод утилизации, вы действительно должны реализовать IDisposable.

1 голос
/ 14 июля 2011

В указанном коде вам ничего не нужно null, вы можете безопасно удалить dispose(), и все будет хорошо.

Если ваши OtherClass1 и / или OtherClass2 являются управляемыми ресурсами , т.е. они реализуют интерфейс IDisposable, то ваш код недостаточно хорош. Затем вам придется связать команду Dispose:

class MainClass : IDisposable
{
   private OtherClass1;
   MainClass()
   {
      OtherClass1 = new OtherClass1();
   }

   public void Dispose()
   {
      OtherClass1.Dispose(); 
      // OtherClass1 = null;  // not needed
   }
}
0 голосов
/ 15 июля 2011

Термин «Dispose» является немного неправильным, так как метод Dispose не удаляет целевой объект, а выполняет запрос к целевому объекту сделать что-либо, что необходимо сделать, прежде чем его можно будет безопасно покинуть.,По сути, это запрос к объекту навести порядок в своих делах.

Наиболее распространенная ситуация, когда конкретному объекту нужно будет навести порядок в своих делах, - это когда некоторые объекты вне него могут что-то делать, сохраняячто-то, воздерживаясь от каких-либо действий или иным образом временно изменяя свое поведение от его имени.Обратите внимание, что объектами могут быть объекты .net, другие типы объектов, распознаваемых ОС (дескрипторы GDI и т. Д.) И т. Д., Но нет особого требования, чтобы объект был каким-то конкретным видом вещей или находился на том же компьютере.или даже любой компьютер.Для того, чтобы объект привел свои дела в порядок, внешние лица, занимающиеся делом, владение и т. Д., Все, что от его имени, нужно было сказать, что им больше не нужно это делать.Если рассматриваемые сущности являются объектами .net, которые реализуют IDisposable, уведомление обычно выполняется путем вызова их метода Dispose.

Обратите внимание, что .net предоставляет средство, с помощью которого объекты могут запрашивать уведомление, если система замечаетчто они были брошены, и используют это как сигнал, чтобы навести порядок в своих делах.Такие уведомления могут поступать не своевременно, и из-за различных факторов они могут быть отложены практически на неопределенный срок, но механизм (называемый «финализация») иногда лучше, чем ничего.

0 голосов
/ 14 июля 2011

Рекомендуется реализовать интерфейс IDisposable и реализовать метод Dispose ().

В Dispose () вы просто освобождаете ресурсы, используемые вашим объектом, такие как любые внешние ресурсы, ссылки COM, соединения с базой данных.и т. д.

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

В общем,если объект потерян (никакая переменная не ссылается на него), он будет находиться в очереди для сбора мусора.

Вы можете вручную вызвать GC.Collect ();но это не рекомендуется, поскольку это мешает механизму сбора мусора .NET.

0 голосов
/ 14 июля 2011

Если на него нет других ссылок, это может быть когда-нибудь мусор. Обратите внимание, что это не детерминированный, вы не можете рассчитывать на то, что он будет собран в определенный промежуток времени.

В общем, вам не стоит слишком беспокоиться об этом, GC в .NET может без проблем обрабатывать циклические ссылки и т. Д. Установка полей на null обычно не требуется. Метод Dispose обычно используется для освобождения неуправляемых ресурсов, таких как соединения с базой данных и т. Д., Детерминистическим способом; речь идет не об освобождении памяти об объекте, который находится.

...