Страницы

Поиск по вопросам

понедельник, 6 января 2020 г.

Garbage collector: перемещение объекта из поколения в поколение

#c_sharp #сборщик_мусора


Когда у нас заполняется нулевое поколение кучи, происходит анализ этого поколения:
удаляются "мёртвые"  объекты и перемещаются "выжившие" в следующее поколение - 1. 
Вопрос: если в поколении 1 недостаточно места для приёма объектов из нулевой кучи,
то что происходит? Очистка первого поколения? 




UPDATE

Цитата (C# 5.0 in Nutshell, Albahari):


  Среда CLR сохраняет раздел Gen() относительно небольшим (максимум 16 Мбайт в 32-битной
версии для рабочей станции, с типичным размером от нескольких сотен Кбайт до нескольких
Мбайт). Когда раздел Gen() заполняется, сборщик мусора GC инициирует сборку Gen() —
что происходит относительно часто. Сборщик мусора применяет похожий порог памяти к
разделу Gen1 (который действует как буфер для Gen2), поэтому сборки Gen1 являются тоже
относительно быстрыми и частыми. Однако полные сборки мусора, включающие Gen2, занимают
намного больше времени и, таким образом, происходят нечасто. Результат полной сборки
мусора показан на рис. 12.2.

    


Ответы

Ответ 1



Достижение поколением порогового размера — всего лишь триггер для начала сборки мусора. Когда общий размер объектов в Gen0 станет больше порога, запустится сборщик мусора. Когда сборщик мусора запустится, он смотрит, не превышает ли суммарный размер объектов в Gen2 порог. Если да, запускается полная, медленная сборка мусора всех трёх поколений. Если Gen2 в порядке, но суммарный размер объектов а Gen1 превышает порог для Gen1, запускается ускоренная сборка, которая рассматривает только Gen0 и Gen1. Если же Gen1 тоже в порядке, то запускается ускоренная сборка только Gen0. Если после сборки Gen0 переполнится Gen1 (то есть, суммарный размер Gen1 станет выше порога), ничего не произойдёт до следующего запуска сборщика мусора. А когда он таки запустится (по переполнению Gen0), он обнаружит переполнение поколения Gen1 и соберёт его тоже. (Кстати, размеры порогов на текущий момент не фиксированы, и фреймворк динамически подгоняет их во время пробега программы.) Литература: Jeffrey Richter. The Managed Heap and Garbage Collection in the CLR.

Ответ 2



Если произойдет "переполнение" (таки у поколений есть пороги) для первого поколения, GC вызовет проверку на первом поколении. Выжившие объекты перейдут во второе, не выжившие - умрут, никакой магии. Рихтер в CLR via C# в главе 21 "Автоматическое управление памятью (уборка мусора)" хорошо описал это.

Комментариев нет:

Отправить комментарий