← Blog

Depurando vazamentos de memória no Node.js

·

Vazamentos de memória em aplicações Node.js podem ser silenciosos por dias até se tornarem um problema real. Neste post descrevo o processo que usei para identificar e corrigir um vazamento em um serviço de mensageria.

O primeiro passo é sempre medir — sem dados, qualquer hipótese é especulação.

Sintomas

A aplicação começou a consumir memória progressivamente ao longo de horas. O heap crescia devagar, os GCs tornavam-se mais frequentes e, eventualmente, o processo morria com `FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed`.

Ferramentas

`process.memoryUsage()` foi o ponto de partida. Adicionei logs periódicos do `heapUsed` para confirmar que havia crescimento real e não apenas variação normal.

Em seguida usei `--inspect` com o Chrome DevTools para capturar heap snapshots em momentos diferentes. A comparação entre snapshots revelou quais objetos acumulavam.

A causa

Um listener de eventos adicionado dentro de um loop de processamento nunca era removido. Cada mensagem processada adicionava um novo listener ao mesmo EventEmitter, e as closures mantinham referências para objetos grandes.

A correção

Mover o registro do listener para fora do loop e garantir que `removeListener` fosse chamado corretamente na finalização do processamento.

O aprendizado: listeners esquecidos são uma das fontes mais comuns de vazamento em aplicações orientadas a eventos. Vale criar convenção de sempre parear `on` com `off` ou usar `once` quando possível.