Читайте также:
|
|
Методы Finalize вызываются при завершении сбора мусора, который происходит в результате одного из пяти следующих событий.
■ Заполнение поколения 0 приводит к запуску сборщика мусора. Это событие намного чаще остальных приводит к вызову метода Finalize, так как является естественным следствием создания новых объектов во время работы кода приложения.
■ Явный вызов статического метода Collect объекта System.GC Код может явно запросить сбор мусора у CLR. Хотя Microsoft настоятельно не рекомендует так поступать, порой принудительный сбор мусора имеет смысл.
■ Windows сообщает о нехватке памяти Для общего мониторинга системной памяти CLR использует Int32-функции CreateMemoryResourceNotification и QueryMemoryResourceNotification. Если Windows сообщает о нехватке памяти, CLR запускает сбор мусора, чтобы освободить нерабочие объекты и уменьшить рабочий набор процесса.
■ Выгрузка домена приложения CLR Выгружая домен приложения, CLR считает, что ни один объект в нем не является корнем, и выполняет сбор мусора всех поколений.
■ Закрытие CLR CLR завершает работу после нормального завершения работы процесса (в отличие от внешнего завершения, например диспетчера задач). При этом CLR считает, что в процессе нет корней, и вызывает метод Finalize для всех объектов в управляемой куче. Учтите, что CLR не пытается сжать или освободить память, потому что процесс завершается, a Windows освобождает всю занятую им память.
CLR использует особый выделенный поток для вызова методов Finalize. В случае первых четырех событий, если метод Finalize зацикливается, выделенный поток блокируется и вызов методов Finalize прекращается. Это очень плохо, потому что приложение не сможет освободить память, занятую объектами, у которых есть метод Finalize, и в итоге будет испытывать нехватку памяти.
В случае пятого события каждому методу Finalize дается примерно 2 секунды на то, чтобы вернуть управление программе. Если он не успевает, CLR просто завершает процесс и методы Finalize больше не вызываются. А если для вызова методов Finalize всех объектов требуется более 40 секунд, CLR также просто завершит процесс.
Когда приложение создает новый объект, оператор new выделяет для него память из кучи. Если в типе объекта определен метод Finalize, прямо перед вызовом конструктора экземпляра типа указатель на объект помещается в список завершения (finalization list) — внутреннюю структуру данных, управляемую сборщиком мусора. Каждая запись этого списка указывает на объект, для которого нужно вызвать метод Finalize, прежде чем освободить занятую им память.
Сборщик сканирует список завершения в поисках указателей на эти объекты. Обнаружив указатель, он удаляет его из списка завершения и добавляет в конец очереди freachable — еще одной внутренней структуры данных сборщика мусора. Каждый указатель в этой очереди идентифицирует объект, готовый к вызову своего метода Finalize.
Дата добавления: 2015-01-30; просмотров: 77 | Поможем написать вашу работу | Нарушение авторских прав |