Ответ
Уменьшение нагрузки на GC напрямую связано с сокращением количества и частоты выделения памяти (аллокаций) в куче (heap). Вот ключевые стратегии:
Сокращайте количество аллокаций:
- Используйте
sync.Pool
: Для повторного использования часто создаваемых, но короткоживущих объектов (например, буферов, JSON-энкодеров). - Предварительно выделяйте память: Для слайсов и мап всегда указывайте
capacity
, если вы можете предсказать их размер. Это предотвращает лишние аллокации при росте. - Передавайте большие структуры по указателю: Передача структуры по значению создает ее копию, что является новой аллокацией. Передача указателя копирует только адрес.
- Используйте
Размещайте данные на стеке, а не в куче:
- Стек работает намного быстрее, и память на нем не отслеживается GC. Компилятор Go использует анализ побега (escape analysis), чтобы определить, можно ли разместить переменную на стеке.
- Чтобы помочь компилятору, избегайте ситуаций, когда переменная "сбегает" в кучу: например, не возвращайте указатели на локальные переменные из функции, если в этом нет необходимости.
- Проверить, сбегает ли переменная, можно с помощью флага компилятора:
go build -gcflags='-m' .
Избегайте утечек памяти:
- Незакрытые горутины: Если горутина блокируется навсегда (например, при чтении из пустого канала), все объекты, на которые она ссылается, никогда не будут освобождены.
- Глобальные коллекции: Будьте осторожны с глобальными мапами или слайсами, которые только растут и никогда не очищаются.
Используйте правильные типы данных:
- Например, для конкатенации строк в цикле
strings.Builder
создает значительно меньше мусора, чем оператор+
.
- Например, для конкатенации строк в цикле
Профилирование памяти:
- Используйте
pprof
для анализа аллокаций. Командыgo tool pprof -alloc_space http://.../debug/pprof/heap
помогут найти места в коде, которые выделяют больше всего памяти.
- Используйте
Тюнинг GC (в крайнем случае):
- Переменная окружения
GOGC
(по умолчанию100
) контролирует, при каком проценте роста новой памяти относительно живой памяти после последней сборки запустится следующая.GOGC=200
заставит GC запускаться реже, но ценой большего потребления памяти. Это компромисс между использованием CPU и RAM.
- Переменная окружения