В чем заключается проблема растущего потребления памяти после релиза
Что проверяют
Умеете ли вы отличить настоящую утечку от нормального поведения рантайма и есть ли у вас порядок действий вместо гаданий. Следом обычно спрашивают, как сравнить профили двух версий и чем утечка горутин отличается от утечки объектов.
Как отвечать
Сначала уточните картину: рост монотонный или пилообразный, растёт куча или RSS процесса, растёт ли вместе с памятью число горутин. Затем по шагам:
- метрики:
go_memstats_heap_inuse_bytesиgo_goroutinesиз стандартного коллектораclient_golang. Если горутины растут вместе с памятью, это почти наверняка их утечка; - профиль кучи:
net/http/pprof, два снимка/debug/pprof/heapс интервалом иgo tool pprof -base old.pb.gz new.pb.gz. Смотритеinuse_space, а неalloc_space: второй показывает всё, что когда-либо выделялось; - профиль горутин:
/debug/pprof/goroutine?debug=1группирует их по стеку, и тысяча одинаковых наchan sendвидна сразу; - дифф релиза: раз рост начался после выкатки, ищите причину в изменениях, по возможности откатите или выкатите канарейку.
Типичные причины в Go: горутина ждёт канал, из которого никто не читает, или запрос без таймаута и отмены через context; не закрыт resp.Body; кэш или глобальная map без ограничения и вытеснения; маленький подслайс держит огромный исходный массив. Карта после delete память не отдаёт, её пересоздают.
Отдельно скажите, что не всякий рост это утечка. GC по умолчанию (GOGC=100) позволяет куче вырасти примерно вдвое от живых данных, а освобождённую память рантайм возвращает системе постепенно. В контейнере задайте GOMEMLIMIT чуть ниже лимита пода, тогда GC начнёт работать активнее раньше, чем придёт OOM killer.
Где спотыкаются
Советуют sync.Pool или ручной runtime.GC() как лечение. Пул снижает число аллокаций, но объект, на который осталась ссылка, не освободит ни он, ни GC.
Смотрят только на RSS в мониторинге и объявляют утечку, не открыв профиль кучи.
Забывают про горутины. Профиль кучи выглядит спокойно, а память съедают стеки тысяч зависших горутин, которые в него не попадают.