A partir do Go 1.27, podemos finalmente detectar goroutine leaks de forma nativa e sem precisar de flags experimentais. Neste post, vamos entender como funciona esse novo perfil de detecção e como usá-lo na prática para evitar um dos bugs mais difíceis de rastrear em aplicações Go.
O que é um Goroutine Leak?
Um goroutine leak ocorre quando uma goroutine fica bloqueada indefinidamente em alguma primitiva de concorrência (channels, sync.Mutex, sync.Cond, etc.) e nunca consegue ser desbloqueada. Diferente de uma goroutine que apenas dorme, uma goroutine em leak está prisioneira — nenhum outro código pode libertá-la.
Isso é um problema sério porque goroutines consomem memória. Se sua aplicação cria milhares delas sem desbloqueá-las, você terá vazamento de memória gradual e difícil de diagnosticar.
Como o Runtime Detecta Leaks
O Go 1.27 usa uma abordagem elegante baseada no garbage collector:
- O runtime executa um ciclo de GC (Garbage Collector)
- Para cada goroutine, verifica se ela está bloqueada em uma primitiva de concorrência
- Verifica se aquela primitiva é alcançável a partir de alguma goroutine que possa ser desbloqueada
- Se a primitiva for inalcançável, a goroutine está vazando
Esse mecanismo funciona porque se uma primitiva é inalcançável, ninguém pode sinalizar para ela, portanto a goroutine nunca acordará.
Leia mais »