Память и GC
Что показывает escape analysis в Go?
Escape analysis решает, можно ли хранить значение на stack конкретной goroutine или оно должно пережить frame и попасть в heap. Причины включают возврат ссылки, захват closure, передачу через interface и слишком сложный для доказательства жизненный цикл, но указатель сам по себе не означает escape. Диагностику компилятора получают через go build -gcflags='-m=2'; вывод объясняет решения, но не измеряет их реальную стоимость. Затем allocation подтверждают benchmark и profile. Ручная перепись ради сообщения компилятора может ухудшить читаемость без заметного выигрыша, особенно вне горячего пути.
Ссылки для изучения
Как уменьшать аллокации в горячем коде Go?
Сначала benchmark с -benchmem и allocation profile показывают, где B/op и allocs/op действительно влияют на latency или GC. Затем заранее задают capacity slice и map, избегают лишних преобразований string/[]byte, переиспользуют буферы с ясным владением и уменьшают escape. sync.Pool подходит временным объектам, но элементы могут исчезнуть в любой GC и pool не является кешем. Переиспользуемый buffer нельзя возвращать caller или конкурентно использовать без копии. Каждую правку повторно измеряют на реалистичных размерах; одна меньшая allocation не всегда быстрее из-за копирования и сложности.
Ссылки для изучения
Как GOGC и memory limit влияют на сборщик мусора?
GOGC задаёт целевой рост live heap относительно heap после предыдущего GC: большее значение обычно реже запускает GC ценой большей памяти, меньшее повышает частоту. GOMEMLIMIT задаёт мягкий лимит памяти, учитываемой runtime, и заставляет GC работать активнее при приближении; это не жёсткий process limit и не включает всю память вне управления Go. Слишком низкий limit может вызвать GC thrashing и потерю throughput. Настройку делают после профиля, наблюдая heap goal, частоту и CPU GC, pauses, RSS и OOM cgroup. Обычно полезнее сначала задать реалистичный memory limit, чем угадывать GOGC.
Ссылки для изучения







