kata academy

Garbage Collector в Go: как устроена одна из самых быстрых систем сборки мусора


Время чтения: 3 минуты
Управление памятью — одна из самых сложных тем для начинающих разработчиков. В языках вроде C или C++ память приходится освобождать вручную, и любая ошибка может закончиться утечкой или падением приложения. В Go этот риск берёт на себя Garbage Collector (GC) — встроенный «уборщик мусора», который автоматически находит и освобождает неиспользуемую память.
Почему GC в Go считается быстрым?
В каждом языке свой инструмент-уборщик или несколько, все они работают по-разному. Некоторые полностью останавливают программу на время очистки памяти, другие делят уборку на этапы, чтобы сократить паузы. В таких случаях работа кода может останавливаться на десятки миллисекунд. C ростом объёма памяти и нагрузки длительность пауз увеличивается. Эти системы уборки проще в реализации, но плохо подходят для серверных приложений: паузы напрямую влияют на задержки и стабильность работы.

Garbage Collector в Go устроен иначе. Основная часть его работы выполняется параллельно с кодом программы, а паузы требуются только для краткой синхронизации и гарантии корректности данных. В типичных сценариях эти паузы очень короткие — обычно 1–2 миллисекунды — и практически не увеличиваются с ростом объёма памяти или числа горутин.

Главная ценность GC в Go — короткие и предсказуемые паузы, а не максимальная экономия памяти. Именно поэтому он отлично подходит для высоконагруженных сервисов, где важен стабильный отклик и низкое время задержки.
IT-калькулятор зарплат
Узнай свою рыночную зарплату за 1 минуту!
Когда GC в Go запускает уборку?
GC в Go работает автоматически и запускается, когда нужно освободить память. Есть три основные причины запуска.

  • Быстрое создание новых объектов — если программа активно выделяет память, например, обрабатывает множество запросов за короткое время.
  • Превышение порога использования heap — heap это область памяти для динамически создаваемых объектов, например структур, массивов или строк, которые живут дольше одного вызова функции. Go следит за занятым пространством и запускает GC, когда его размер достигает определённого порога. Этот порог задаёт встроенная переменная GOGC. По умолчанию GOGC = 100, что означает: GC срабатывает, когда heap достигает примерно двукратного объёма живых объектов. Значение можно изменить, чтобы регулировать частоту сборки мусора.
  • Профилактическая очистка — даже без явной нагрузки runtime (среда выполнения Go) может инициировать GC, чтобы поддерживать стабильную работу приложения.
Как работает Garbage Collector в Go?
После того как программа зафиксировала одну из вышеуказанных причин, запускается GC и проходит память в два этапа, не останавливая программу целиком.

1. Разметка (Mark)
Сначала GC определяет, какие объекты всё ещё используются программой. Он начинает с корней:
  • глобальные переменные,
  • стеки всех горутин,
  • внутренние структуры runtime.

Далее GC проходит по ссылкам между объектами. Если до объекта можно добраться из выполняющегося кода, он помечается как «живой». Из него GC идёт дальше по ссылкам, постепенно помечая все необходимые объекты.

Большая часть этой работы выполняется параллельно с кодом приложения, поэтому программа продолжает работать во время сборки мусора.

2. Очистка (Sweep)
Когда разметка завершена, все помеченные объекты остаются в памяти, а непомеченные считаются мусором
GC освобождает память и подготавливает её для повторного использования внутри программы или для операционной системы.

Короткие остановки приложения
Большая часть работы идёт параллельно с программой, но в некоторых моментах могут быть паузы на миллисекунды, чтобы гарантировать корректность данных.
Практические советы для работы с GC
Хотя GC в Go работает автоматически, программист может влиять на его эффективность.

  • Настроить GOGC — переменная определяет порог запуска GC. Меньшее значение GOGC заставляет GC запускаться чаще, а большее — реже.
  • Использовать структуры sync.Pool для короткоживущих объектов, которые часто создаются и быстро становятся мусором. Долгоживущие данные лучше хранить отдельно, чтобы GC их не удалял.
  • Сократить число объектов с коротким жизненным циклом, чтобы уменьшить нагрузку на GC и количество пауз. Для этого можно повторно использовать объекты через sync.Pool, уменьшить ненужные временные аллокации в циклах, рационально использовать массивы и буферы вместо постоянного создания новых объектов.
Узнай больше про Go-разработку на курсе с гарантией трудоустройства. Обучение проходит с поддержкой ментора. Внести основную оплату за курс можно после выхода на работу. Подробности на нашем сайте.

Статьи для старта в IT

Истории наших выпускников

Стань тем, кто задаёт тон в IT!
Подпишись на нашу рассылку и первым получай статьи по Java, JavaScript, Golang и QA. Позволь себе быть экспертом!