MXStat
MXStat
Введите текст для поиска
Расширенный поиск каналов
  • Вход на сайт
  • Каталог
    Каталог каналов Региональные подборки Поиск каналов
    Добавить канал
  • Рейтинги
    Рейтинг каналов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Max
Библиотека Go (Golang) разработчика

30 Jul, 11:13

Открыть в Max Поделиться

Как спасти сборщик мусора от перегрева: используем sync.Pool 🛟

В продолжение темы про аллокации в куче. Если ваш высоконагруженный бэкенд создает тысячи временных объектов в секунду (например, буферы для сборки ответов на HTTP-запросы или парсинга JSON), сборщик мусора (GC) начинает задыхаться, сжигая драгоценное процессорное время.

Чтобы не выделять память каждый раз заново, в Go есть встроенный и мощный инструмент - sync.Pool.

Что это такое?
Это потокобезопасный механизм для хранения и переиспользования временных объектов.

Как это работает:

• Метод Get() достает объект из пула. Если пул пуст, автоматически вызывается функция New, которая создает новый экземпляр.
• Метод Put() возвращает объект обратно в пул после того, как он стал не нужен.

Где это реально полезно?
Идеальный кандидат для пула - bytes.Buffer, массивы байт для чтения из сети или тяжелые структуры данных. Популярные пакеты вроде fmt, encoding/json или сверхбыстрый логгер zap от Uber активно используют sync.Pool под капотом именно для снижения нагрузки на GC.

Важные нюансы (на которых часто обжигаются):

• Это не кэш. Сборщик мусора имеет полное право очистить sync.Pool в любой момент (обычно во время очередного цикла сборки), удалив объекты, которые сейчас не используются. Не пытайтесь хранить там постоянные соединения с БД или пользовательские сессии.
• Всегда сбрасывайте состояние. Перед тем как вернуть объект через Put(), его нужно очистить (например, вызвать Reset()). Иначе следующая горутина, вызвавшая Get(), получит объект с чужими «грязными» данными, что приведет к плавающим и трудноотловимым багам.

Пример правильного использования:

var bufPool = sync.Pool{
New: func() any {
return new(bytes.Buffer) // Вызывается только если пул пуст
},
}

func process() {
// Берем буфер из пула и кастуем к нужному типу
buf := bufPool.Get().(*bytes.Buffer)

// Гарантируем очистку и возврат буфера
defer func() {
buf.Reset() // Очищаем старые данные!
bufPool.Put(buf)
}()

// ... работаем с buf ...
}

#golang #backend #performance #память

👉 @golang_lib

514 8
Каталог
Каталог каналов Подборки каналов Поиск каналов Добавить канал
Рейтинги
Рейтинг каналов Max
Контакты
Написать в Max Написать в Telegram Написать на почту
Всякая всячина
Пользовательское соглашение Политика конфиденциальности
Наши каналы
MXStat в Telegram MXStat в Max
Наши боты
MXAuthBot MXAnalyticsBot
Made by TGStat