Зачем выбрасывать объект, который, несомненно, скоро будет удален?

Предположим, что у меня есть процедура, например. нажмите кнопку.

И я создаю объект Graphics.

По-видимому, я должен распоряжаться им, например.

using(Graphics gr__=this.CreateGraphics())  {

} 

или с вызовом .Dispose() в finally try-catch-finally.

Но учитывая, что процедура скоро закончится.

Предположим, что я создаю его локальным для процедуры (не глобально, а не при использовании). Но локально к процедуре.

Тогда, как и любые другие переменные, он автоматически удаляется, когда процедура завершается, не так ли?

Итак, почему мне важно вручную или явно распоряжаться им?

Почему я не могу позволить этому мусору автоматически собираться как любая другая переменная?

Уверен, что он может быть немного больше, чем "int", но он все еще может быть довольно маленьким и не будет в памяти надолго, так как процедура так быстро заканчивается. Возможно, даже после завершения использования или вызова Dispose() процедура заканчивается, и, я полагаю, она была бы удалена, если бы эта переменная была локальной процедурой. Итак, зачем беспокоиться о явной сборке мусора Dispose()/using?

Ответ 1

Библиотека классов Microsoft.NET предоставляет управляемый интерфейс для GDI + через пространство имен System.Drawing. GDI + основан на С++ и дает ссылки на не управляемые объекты. Поэтому важно располагать одноразовые объекты пространства имен System.Drawing, так как не связанные с ним объекты не удаляются автоматически сборщиком мусора. Эти объекты могут содержать финализаторы, которые выполняют эту работу; однако вы не контролируете выполнение этих финализаторов. Также ожидающие завершения финализаторы загромождают кучу. Поэтому лучше называть Dispose() явно или с помощью using -статеймента.

Ответ 2

Здесь есть две разные концепции.

  • Располагая
  • Коллекция мусора

Между этими двумя понятиями существует большая разница.

Несмотря на то, что Graphics удаляется при сборе GC, но почему вы должны ждать выполнения GC и увеличения кадров в памяти вашего приложения?

Вот код для Graphics деструктора.

~Graphics()
{
  try
  {
    this.Dispose(false);
  }
  finally
  {
    // ISSUE: explicit finalizer call
    // ISSUE: explicit non-virtual call
    __nonvirtual (((object) this).Finalize());
  }
}

Подробнее

Основы сбора мусора

что такое связь между GC, Finalize() и Dispose?

Что и где находятся стек и куча?

Ответ 3

Тогда, как и любые другие переменные, он автоматически удаляется, когда процедура завершается, не так ли?

К сожалению, это не всегда относится ко всем классам System.Drawing(edit: read dotctor answer)

Есть и другие сложные классы, такие как Bitmap, где, хотя он "управляется", но размер невелик. Таким образом, всякий раз, когда это будет поздно, он будет выходить из памяти!

Лучше практиковать диполяцию неиспользуемого объекта до утечки памяти.

Детали более сложны, хотя.

Вы можете искать больше на неуправляемом ресурсе в System.Drawing, чтобы понять это больше.

Ответ 4

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

Перед удалением некоторые объекты будут ссылаться на ресурсы, которые будут использовать вашу память, или блокировать некоторые операции. Поэтому хорошо распоряжаться этими объектами, как только они больше не используются.

Я работал над ошибкой, когда временный файл базы данных SQLite не мог быть удален после использования, но только иногда! После трех разочаровывающих дней исследований я обнаружил, что проблема связана с объектом командной строки SQLite, который не был своевременно удален.

Поэтому используйте using;-)