Ответ вслух Senior Память, GC и pprof обновлено

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

Вопрос

Расскажите, как работает GC в Go, как его настраивать и как вы разбирали проблемы с памятью.

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Сборщик Go конкурентный, трёхцветный, mark-and-sweep, неперемещающий и без поколений. Цикл начинается короткой паузой, где включается write barrier.

Что должно прозвучать в ответе

  • Конкурентный трёхцветный 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 ошибок.