Ответ
Сборщик мусора (GC) в Go работает конкурентно с основной программой и спроектирован для минимизации пауз (low-latency). Однако его работа всё равно влияет на производительность.
Основное влияние:
- Паузы "Stop-The-World" (STW): Хотя GC в Go большую часть времени работает параллельно, у него есть очень короткие фазы, когда все горутины приложения останавливаются. В современных версиях Go эти паузы обычно составляют доли миллисекунды, но в высоконагруженных системах могут стать заметными.
- Потребление CPU: Сам процесс сборки мусора отнимает процессорное время у приложения.
Как минимизировать влияние GC:
-
Уменьшение количества аллокаций (самый эффективный способ):
- Переиспользование объектов с помощью
sync.Pool
. Идеально для временных объектов, которые дорого создавать (например, буферы). -
Предварительное выделение памяти для слайсов и карт, если их итоговый размер известен. Это позволяет избежать многократных реалокаций.
// Плохо: слайс будет много раз реалоцироваться s := make([]int, 0) for i := 0; i < 1000; i++ { s = append(s, i) } // Хорошо: одна аллокация под нужный размер s := make([]int, 0, 1000) for i := 0; i < 1000; i++ { s = append(s, i) }
- Избегайте передачи указателей в каналы, если это приводит к "утеканию" объекта в кучу (heap escape).
- Переиспользование объектов с помощью
-
Профилирование: Используйте встроенный профайлер
pprof
для поиска мест в коде, которые создают больше всего мусора.# Сбор профиля памяти go tool pprof http://localhost:6060/debug/pprof/heap
-
Тюнинг GC: Переменная окружения
GOGC
(по умолчанию100
) контролирует, когда запускать следующую сборку мусора.GOGC=100
означает, что GC запустится, когда размер кучи увеличится на 100% (вдвое) с момента прошлой сборки.GOGC > 100
: GC запускается реже, потребляет больше памяти, но меньше CPU.GOGC < 100
: GC запускается чаще, экономит память, но больше нагружает CPU.