1 просмотров

Утилизация объектов

Скомканные шарики бумаги рядом с мусорной корзиной

Дэн Маббатт — эксперт по Visual Basic, создавший обучающие курсы для пользователей Visual Basic. Он является соавтором двух книг на эту тему.

В статье «Кодирование новых экземпляров объектов» я писал о различных способах Новый экземпляры объектов могут быть созданы. Противоположная проблема, избавление от объекта, — это то, о чем вам не придется беспокоиться в VB.NET очень часто. .NET включает в себя технологию, называемую Уборщик мусора (ГК), который обычно делает все за кулисами тихо и эффективно. Но иногда, обычно при использовании файловых потоков, объектов sql или графических (GDI+) объектов (т. е. неуправляемые ресурсы), вам может потребоваться управлять удалением объектов в собственном коде.

Во-первых, некоторая предыстория

Так же, как противструктор (т. Новый ключевое слово) создает новый объект, деstructor — это метод, который вызывается при уничтожении объекта. Но есть одна загвоздка. Люди, которые создали .NET, поняли, что это формула ошибок, если два разных фрагмента кода действительно могут уничтожить объект. Таким образом, .NET GC фактически находится под контролем, и обычно это единственный код, который может уничтожить экземпляр объекта. Сборщик мусора уничтожает объект, когда решит, а не раньше. Обычно после того, как объект покидает область видимости, он вышел общеязыковой средой выполнения (CLR). ГК разрушает объекты, когда среде CLR требуется больше свободной памяти. Итак, суть в том, что вы не можете предсказать, когда GC действительно уничтожит объект.

(Хорошо. Это правда Около Все время. Вы можете позвонить GC.Collect и форсировать цикл сборки мусора, но власти повсеместно говорят, что это Плохо Идея и совершенно ненужная.)

Например, если ваш код создал Покупатель объект, может показаться, что этот код снова его уничтожит.

Клиент = ничего

Но это не так. (Установка объекта в Nothing обычно называется разыменование объект.) На самом деле это просто означает, что переменная больше не связана с объектом. Через некоторое время GC заметит, что объект доступен для уничтожения.

Кстати, для управляемых объектов ничего из этого на самом деле не нужно. Хотя такой объект, как Button, предлагает метод Dispose, его использование необязательно, и мало кто его использует. Компоненты Windows Forms, например, добавляются в объект-контейнер с именем составные части. Когда вы закрываете форму, ее метод Dispose вызывается автоматически. Обычно вам нужно беспокоиться обо всем этом только при использовании неуправляемых объектов, да и то только для оптимизации вашей программы.

Рекомендуемый способ высвобождения любых ресурсов, которые могут удерживаться объектом, — это вызвать метод Утилизировать метод для объекта (если он доступен), а затем разыменовать объект.

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

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

В серии GDI+ С использованием block довольно часто используется для управления этими надоедливыми графическими объектами. Например .

моя кисть удаляется автоматически, когда выполняется конец блока.

Подход GC к управлению памятью сильно отличается от того, как это делал VB6. COM-объекты (используемые VB6) уничтожались, когда внутренний счетчик ссылок достигал нуля.Но было слишком легко ошибиться, поэтому внутренний счетчик был отключен. (Поскольку память была занята и недоступна для других объектов, когда это произошло, это назвали «утечкой памяти».) Вместо этого сборщик мусора фактически проверяет, ссылается ли что-либо на объект, и уничтожает его, когда ссылок больше нет. Подход GC имеет хорошую историю в таких языках, как Java, и является одним из больших улучшений в .NET.

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

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

———
Щелкните здесь, чтобы отобразить иллюстрацию
Нажмите кнопку «Назад» в браузере, чтобы вернуться
———

Добавленный код выглядит следующим образом (VB.NET 2008):

Утилизировать является почти «принудительным» шаблоном проектирования разработчиков в .NET. На самом деле есть только один правильный способ сделать это, и это он. Вы можете подумать, что этот код делает что-то волшебное. Это не так.

Во-первых, обратите внимание, что внутренний флаг распоряжаться просто закорачивает все это, чтобы вы могли позвонить Утилизировать (распоряжаться) так часто, как вам нравится.

. делает ваш код более эффективным, сообщая сборщику мусора, что объект уже удален («дорогая» операция с точки зрения циклов выполнения). Finalize защищен, потому что сборщик мусора вызывает его автоматически при уничтожении объекта. Вы никогда не должны вызывать Finalize. логическое значение распоряжаться сообщает коду, инициировал ли ваш код удаление объекта (True) или это сделал GC (как часть Завершить суб. Обратите внимание, что единственный код, использующий логическое значение распоряжаться является:

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

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

Когда вы наследуете класс от базового класса, который реализует IDisposable, вам не нужно переопределять какие-либо из базовых методов, если только вы не используете другие ресурсы, которые также необходимо удалить. В этом случае производный класс должен переопределить метод Dispose(dispose) базового класса, чтобы избавиться от ресурсов производного класса. Но не забудьте вызвать метод Dispose(disposing) базового класса.

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

голоса
Рейтинг статьи
Статья в тему:  Пуэбло Бонито: большой дом каньона Чако в Нью-Мексико
Ссылка на основную публикацию
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x