Soru tarihi:
Goroutine leak, anlamını yitirmiş olmasına rağmen (hesaplamalar tamamlandı, veriler gerekmez, ancak çıkış koşulu yok) goroutine'in bellek içinde var olmaya devam etmesi durumudur. Bellek sızıntılarına benzer, ancak yürütme akışları için geçerlidir. Go için bu kritiktir — yüksek yük, kaynakların tükenmesine yol açabilir.
Sorun:
Diğer dillerin aksine, burada doğrudan thread'leri yönetmek genellikle onların manuel olarak kapatılmasına yol açarken, Go'da goroutineler kolayca başlatılır ancak her zaman düzgün bir şekilde sonlandırılmaz. Yaygın bir hata: ana mantık sona erdi, ancak goroutine "donmuş" durumda — kapalı bir kanalda veri bekliyor veya sinyal almak için hiç beklemiyor.
Çözüm:
Sızıntıları önlemek için kontrol edici yapılar kullanılır: context, kanalların kapatılması, sinyal değişkenleri. Her goroutine için çıkış yollarını önceden tasarlamak, temizlemek için defer kullanmak önemlidir. Örnek:
func worker(ctx context.Context, jobs <-chan int, results chan<- int) { for { select { case <-ctx.Done(): return case job, ok := <-jobs: if !ok { return } results <- job * 2 } } }
Anahtar özellikler:
Goroutine'i durdurmak için kanalı kapatmak yeterli mi?
Her zaman değil. Select'te başka case'ler varsa veya kapatmanın kontrolü ok ile yapılmamışsa, goroutine "asılı" kalabilir.
val, ok := <-ch if !ok { return } // Bu daha doğru
Select içinde context.Done'ı işlersem ne olur?
Goroutine asla iptal olduğunu fark etmez — "sonsuz" kalır. Bu doğrudan bir leak yoludur.
Leak'i go runtime ile yakalamak mümkün mü?
Standart bir leak izleme aracı yoktur. Aktif goroutine sayısını runtime.NumGoroutine ile izlemek veya üçüncü parti kütüphanelerin leak dedektörünü kullanmak gereklidir.
Push bildirimleri gönderimi sisteminde her gelen mesaj için bir goroutine başlatılır, ancak context iptal edildiğinde veya kanal kapatıldığında durdurmayı unutur — bellek içinde yüzlerce "ölü" goroutine kalır.
Artılar:
Eksiler:
Goroutine'in çalışması context ile kontrol edilir, iş mantığı seviyesinde select'ten çıkış kontrol edilir, başarılı bir gönderim/işlemden sonra kanal kapatılır.
Artılar:
Eksiler: