Sua aplicação Node.js começa a consumir mais RAM a cada hora, sem motivo aparente? Memory leak Node.js é um vazamento silencioso: objetos que deveriam ser coletados pelo garbage collector continuam referenciados. O resultado é queda de performance e reinícios forçados. Este guia mostra como rastrear o problema com heap snapshots e métricas. Pré-requisitos: Node.js 18+, acesso ao ambiente de produção ou staging e familiaridade com Chrome DevTools.
Passo 1: Meça o crescimento do heap
Antes de qualquer ferramenta, colete dados. Use process.memoryUsage() em intervalos regulares e registre heapUsed. Um crescimento contínuo após o GC indica vazamento. Evite olhar apenas o RSS, que inclui memória fora do heap. Dica: rode node --expose-gc e chame global.gc() para forçar a coleta antes de medir. Erro comum: confundir picos de alocação com vazamento real.
Passo 2: Gere heap snapshots comparativos
Com node --inspect, conecte o Chrome DevTools e capture um snapshot inicial. Aguarde o consumo subir e capture outro. Compare a aba "Comparison" para ver objetos que cresceram. Procure por arrays, closures e listeners acumulados. Dica: nomeie snapshots com timestamp. Erro comum: analisar um único snapshot sem linha de base.
Passo 3: Isole a origem no código
Com os objetos suspeitos identificados, rastreie referências. Caches sem limite, event listeners não removidos e timers ativos são causas frequentes. Use clinic.js ou heapdump para capturas em produção. Dica: teste em staging com carga similar. Erro comum: corrigir sem reproduzir o cenário.
Passo 4: Valide a correção
Após ajustar o código, repita as medições do Passo 1 por pelo menos 30 minutos. O heap deve estabilizar após o GC. Monitore com APM (New Relic, Datadog) para garantir que não há regressão. Erro comum: considerar resolvido sem monitoramento contínuo.
Checklist rápido
- Métricas de
heapUsedcoletadas e comparadas. - Heap snapshots gerados e analisados em conjunto.
- Objetos com crescimento anormal identificados.
- Causa raiz corrigida (cache, listener, timer).
- Validação pós-correção com monitoramento.
FAQ
O que causa memory leak em Node.js?
As causas mais comuns são caches sem limite de tamanho, event listeners não removidos, timers ativos e closures que mantêm referências. Módulos globais também podem acumular dados indefinidamente. Identificar o padrão de crescimento ajuda a direcionar a investigação.
Como usar heap snapshot para encontrar vazamentos?
Gere dois snapshots com intervalo de tempo e compare. O DevTools mostra objetos que aumentaram em quantidade ou tamanho. Filtre por "Objects allocated between snapshots" para focar no que cresceu. Analise as referências que mantêm esses objetos vivos.
Qual a diferença entre memory leak e alto consumo de memória?
Alto consumo pode ser esperado, como em processamento de grandes arquivos. Memory leak é o crescimento contínuo sem liberação após o garbage collector. O segundo indica que referências estão sendo mantidas indevidamente, mesmo quando o objeto não é mais necessário.
Ferramentas gratuitas para debugar memory leak Node.js?
Chrome DevTools (via --inspect), heapdump e clinic.js são opções gratuitas. O próprio Node.js oferece process.memoryUsage() e --expose-gc. Para produção, ferramentas de APM como New Relic e Datadog têm planos pagos, mas oferecem monitoramento contínuo.
Com que frequência devo monitorar a memória?
Em produção, monitore continuamente com alertas para crescimento anormal. Em desenvolvimento, meça antes e depois de mudanças críticas. A frequência depende da carga da aplicação. O importante é ter uma linha de base e detectar desvios rapidamente.