Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПРИС_шпоры.doc
Скачиваний:
3
Добавлен:
01.03.2025
Размер:
3 Мб
Скачать
☆

6. .Net Framework. Механизм сборки мусора.

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

Сборка мусора – метод освобождения динамической памяти путем автоматического удаления объектов в случае отсутствия ссылок на них

 занимает время

 недетерминирована (выполняется по инициативе CLR, а не приложения)

 существует механизм принудительной сборки мусора

Деструктор – метод, вызывающийся CLR непосредственно перед уничтожением

объекта сборщиком мусора

 синтаксис:

~имя_класса()

{тело}

 нельзя предсказать, когда будет выполнен деструктор

Начиная работу, сборщик предполагает, что все объекты в куче — мусор. Ина­че говоря, он предполагает, что в стеке потока нет переменных, ссылающихся на объекты в куче, а также что на объекты в куче не ссылаются регистры процессо­ра и статические поля. Затем сборщик переходит к этапу сбора мусора, называе­мому маркировка (marking). Он проходит по стеку потока и проверяет вес кор­ни. Если окажется, что корень ссылается на объект, в поле SyncBlocklndex этого объекта будет включен бит — именно так объект маркируется. Например, сбор­щик мусора может найти локальную переменную, указывающую на объект в куче. На рис. 20-3 показана куча с несколькими объектами, в которой корни приложе­ния напрямую ссылаются на объекты А, С D и F. Все эти объекты маркируются. При маркировке объекта D сборщик мусора замечает, что в этом объекте есть поле, ссылающееся на объект Н. Поэтому объект Н также помечается. Затем сборщик продолжает рекурсивный просмотр всех достижимых объектов,

После маркировки корня и объекта, на который ссылается его поле, сборщик мусора проверяет следующий корень и продолжает маркировать объекты. При попытке пометить объект, уже помеченный ранее, сборщик мусора останавлива­ется. Это нужно по двум причинам. Во-первых, заметно повышается быстродействие, так как сборщик проходит набор объектов не больше одного раза, а во-вторых, исключается возможность бесконечных циклов, возникающих из-за зам­кнутых связных списков объектов.

После проверки всех корней куча содержит набор маркированных и немар­кированных объектов. Маркированные объекты, в отличие от немаркированных, достижимы из кода приложения. Недостижимые объекты считаются мусором, а занимаемая ими память становится доступной для освобождения. Затем сборщик переходит к следующему этапу сбора мусора, называемому сжатие (compact phase). Теперь он проходит кучу линейно в поисках непрерывных блоков немаркирован­ных объектов, то есть мусора.

Небольшие блоки сборщик не трогает, а в больших непрерывных блоках он перемещает вниз все «немусорные» объекты, сжимая таким образом кучу.

Естественно, перемещение объектов в памяти делает все переменные и реги­стры процессора, содержащие указатели на объекты, недействительными. Поэтому сборщик мусора должен вновь проверить и обновить все корни приложения, чтобы все значения корней указывали на новые адреса объектов в памяти. Кроме того, если объект содержит поле, указывающее на другой перемещенный объект, сбор­щик должен исправить и эти поля. После сжатия памяти кучи в указатель NextObjPtr управляемой кучи заносится первый адрес за последним объектом, не являющимся мусором. На рис. 20-4 показана управляемая куча после сбора мусора.

Как видите, сбор мусора сильно бьет по производительности — это основной недостаток управляемой кучи. Однако не следует забывать, что сбор мусора на­чинается только после заполнения поколения 0, а до этого управляемая куча ра­ботает намного быстрее, чем куча исполняющей среды С. Наконец, ряд оптими­заций сборщика мусора CLE существенно повышает производительность сбора мусора.

Завершение (finalization) — это механизм, поддерживаемый CLR, который по­зволяет объекту выполнить корректную очистку, прежде чем сборщик мусора освободит занятую им память. Любой тип, выполняющий функцию оболочки машинного ресурса, например файла, сетевого соединения, сокста, мыотекса и других, должен поддерживать завершение. Для этого в типе реализуют метод Finalize. Определив, что объект стал мусором, сборщик вызывает метод Finalize объекта (если он есть). Иначе говоря, если в типе реализован метод Finalize, это означает, что все его объекты имеют право на исполнение «последнего желания перед экзекуцией».