tgoop.com/go_interview_lib/409
Last Update:
💬 Почему использование time.After для установки таймаутов может привести к утечке памяти в Go. Как можно предотвратить эту проблему?
Использование time.After
для создания таймеров или установки таймаутов может привести к утечке памяти из-за особенностей работы сборщика мусора Go. Когда мы вызываем time.After(d)
, создается канал, который закроется после задержки d
.
Однако таймер, созданный time.After
, не будет собран сборщиком мусора до тех пор, пока не истечет задержка времени. Это означает, что даже если канал выходит из области видимости, он остается в памяти до тех пор, пока не истечет таймер.
В приведенном ниже примере код обрабатывает события из канала и выводит предупреждение, если за 15 минут не поступило ни одного события:
func consumer(ch <-chan Event) {
for {
select {
case event := <-ch:
handle(event)
case <-time.After(time.Minute * 15) :
fmt.Println("warning: no messages received")
}
}
}
При высоком потоке событий это может привести к утечке памяти. Каждый раз, когда вызывается
time.After
, создается новый канал, который остается в памяти до истечения таймера.📌 Как предотвратить проблему утечки памяти?
Для предотвращения этой проблемы можно использовать
time.NewTimer
и явным образом останавливать таймер, когда он больше не нужен:
func consumer(ch <-chan Event) {
for {
timer := time.NewTimer(time.Minute * 15)
select {
case event := <-ch:
handle(event)
if !timer.Stop() {
<-timer.C
}
case <-timer.C:
fmt.Println("warning: no messages received")
}
}
}
В примере таймер создается с использованием
time.NewTimer
, и мы явным образом останавливаем его с помощью timer.Stop()
после обработки события. Это предотвращает создание множества неиспользуемых таймеров, которые могут привести к утечке памяти.👉 Подробнее:
• Go Documentation: time.After
• Effective Go: Memory Management
• Go Memory Management
BY Библиотека Go для собеса | вопросы с собеседований
Share with your friend now:
tgoop.com/go_interview_lib/409