Тихая смерть памяти c time.After — 13 апреля 2026 г. в 07:55:32.899
Тихая смерть памяти c time.After Внутри select часто используют таймеры для отмены долгих операций. Но есть нюанс, который может положить вам прод по памяти, если у вас высокий RPS или быстрые циклы. Смотрим код: for { select { case msg := <-ch: process(msg) case <-time.After(3 * time.Minute): return errors.New("timeout") } } В чем проблема? time.After создает таймер, который не собирается мусорщиком, пока не истечет его время. Даже если case msg := <-ch сработает мгновенно, таймер на 3 минуты останется висеть в памяти. В цикле с высокой нагрузкой вы создадите тысячи таймеров, которые будут ждать свои 3 минуты, пожирая хип. Решение: Используйте time.NewTimer и останавливайте его вручную. timer := time.NewTimer(3 * time.Minute) defer timer.Stop() for { timer.Reset(3 * time.Minute) select { case msg := <-ch: process(msg) if !timer.Stop() { <-timer.C } case <-timer.C: return errors.New("timeout") } } Да, кода больше. Да, выглядит не так элегантно. Зато OOM Killer не придет к вам ночью. #golang #performance #memory_leak 👉 @golang_lib

