Как работает сборщик мусора .NET
Вопрос
Расскажите, как работает сборщик мусора в .NET.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Трассирующий: помечает достижимое от корней, остальное мусор
Поколения 0, 1, 2 и гипотеза о ранней смерти объектов
Уплотнение кучи и обновление ссылок, LOH и POH
Остановка потоков на время сборки, фоновая сборка поколения 2
Финализаторы и очередь финализации
Режимы Workstation и Server, настройки в контейнерах
Что могут спросить следом
- Почему циклические ссылки не проблема для .NET GC?
- Что такое LOH и почему её фрагментация вредна?
- Как найти утечку памяти?
Разбор
Сборщик мусора в .NET трассирующий и уплотняющий. Он стартует от корней: локальных переменных в стеках потоков, статических полей, закреплённых дескрипторов. Всё достижимое помечается как живое, остальное считается мусором. Поэтому циклические ссылки не мешают: если до цикла не добраться от корней, он соберётся.
Куча разделена на поколения. Новые объекты попадают в поколение 0, его собирают часто и быстро. Выжившие переезжают в 1 и 2, полная сборка поколения 2 редкая. После пометки живые объекты сдвигаются, ссылки обновляются, а выделение памяти сводится к сдвигу указателя. Объекты от 85 000 байт живут в LOH, которая по умолчанию не уплотняется, а закреплённые объекты в .NET 5+ можно выделять в отдельной POH.
На время сборки потоки приложения приостанавливаются, но поколение 2 может собираться фоново. В ASP.NET Core по умолчанию Server GC: куча и поток сборки на ядро. Для поиска утечек снимаю дамп dotnet-gcdump или dotnet-dump и смотрю, какие корни держат объекты.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.