sync.Pool
Буферы загрузки создавались на каждый запрос заново, и сборщик мусора собирал их тысячами. Миша завёл общий пул: отработанный буфер возвращался в него и доставался следующему запросу. Память перестала скакать на пиках.
sync.Pool — кэш временных объектов: Get забирает готовый, создаёт через New или возвращает nil, Put кладёт обратно без гарантии сохранения; это способ переиспользовать аллокации и снять давление с GC.
Буферы для ответов
Что здесь показано
- Стек — локальные переменные функции.
i = 3— значение;p = ptr → 10— указатель на значение;b = "hello"— срез (заголовок: указатель + длина + ёмкость). - Куча — данные, на которые ссылаются переменные:
rodata— байты строки-литерала (в бинарнике),данные N Б— бэкинг-массив слайса,строка— динамическая строка. - Горутины — лёгкие потоки Go: статус (running/runnable/waiting…), функция, в которой каждая сейчас находится, размер стека (растёт по мере работы) и пометка «из main» — горутина запущена из твоего кода.
- GC — сборщик мусора: фаза (off/mark) и число завершённых циклов.
Get возвращает объект из пула или, если пул пуст, создаёт через New. Без New при пустом пуле Get вернёт nil. Put кладёт объект обратно, но не гарантирует, что он там останется. Вместо аллокации на каждый запрос — переиспользование: сервер с тысячами запросов в секунду экономит тысячи буферов.
Почему Reset обязателен
Get может вернуть объект, которым уже пользовались, — с остатками прошлых данных. Поэтому перед Put объект приводят в нулевое состояние: buf.Reset — и только потом возвращают. Положил «грязный» объект — получил грязные данные в следующем запросе.
Чего Pool не обещает
Пул — не гарантированное хранилище: GC может очистить его целиком в любой момент. Объекты из пула — строго временные, между Get и Put. Для долгоживущих вещей (соединения, кэши) Pool не подходит: они должны пережить сборку мусора, а пул — нет.
Вы узнаете:
- как пул снижает давление на GC
- когда Pool не даёт выигрыша
Проверьте себя
Объект положили в sync.Pool и вызвали runtime.GC(). Что вернёт следующий Get?
Зачем делать Reset перед Put?
Для чего на самом деле нужен sync.Pool?
правильных ответов
Pool — переиспользование временных объектов: Get/Put с Reset; без New пустой Get даёт nil, положенное может исчезнуть в любой момент. Это про снижение давления на GC, а не про кэш.
10 000 ₽ · 60 минут · онлайн