Как работает сборщик мусора Go
Вопрос
Расскажите, как работает GC в Go, как его настраивать и как вы разбирали проблемы с памятью.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Конкурентный трёхцветный mark-and-sweep, без поколений и перемещений
Фазы: STW на включение write barrier, конкурентная маркировка с mark assist, STW на завершение, ленивый sweep
Pacer: старт по GOGC с учётом стеков и глобальных, цель около 25% CPU
GOMEMLIMIT как мягкий лимит, рекомендация для контейнеров
Escape analysis снижает нагрузку: короткоживущие объекты на стеке
Диагностика: gctrace, pprof heap inuse/alloc, метрики runtime/metrics
Что могут спросить следом
- Почему в Go нет поколенческого GC?
- Что такое mark assist и почему он увеличивает задержки?
- Что такое Green Tea GC?
Разбор
Сборщик Go конкурентный, трёхцветный, mark-and-sweep, неперемещающий и без поколений. Цикл начинается короткой паузой, где включается write barrier. Дальше маркировка идёт параллельно программе: фоновые воркеры GC занимают около четверти CPU, а горутины, которые активно выделяют память, привлекаются к маркировке (mark assist), это и даёт рост задержек под нагрузкой. Потом вторая короткая пауза на завершение маркировки и ленивый sweep. Когда стартовать, решает pacer: по GOGC, по умолчанию при росте кучи вдвое от живой, с Go 1.18 с учётом стеков и глобальных. GOMEMLIMIT задаёт мягкий потолок, в контейнере ставлю его на 85-90% лимита. Поколений нет, потому что escape analysis и так оставляет много короткоживущего на стеке, а неперемещающий GC проще сочетается с указателями наружу. В Go 1.25 появился экспериментальный Green Tea, который сканирует память блоками и лучше использует кеш. На практике разбирал так: GODEBUG=gctrace=1 для частоты циклов, heap-профиль alloc_space для горячих аллокаций, inuse_space и сравнение снимков для утечки, плюс метрики из runtime/metrics в Prometheus.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «Память, GC и pprof»
- Пул объектов как sync.Pool: симуляция на Go
- Статистика потока чисел без хранения на Go
- Как посмотреть решения escape analysis
- Что значит GOGC=100
- GOMEMLIMIT в контейнере
- inuse_space и alloc_space в pprof
- Почему fmt.Println вызывает аллокации
- Инструменты диагностики Go