{
“@context”: “https://schema.org”,
“@type”: “TechArticle”,
“headline”: “Como depurar vazamentos de memória em Node.js: guia passo a passo completo 2026”,
“description”: “Diagnosticar e corrigir vazamentos de memória do Node.js usando Chrome DevTools, clinic.js e sinalizador –inspect. Abrange padrões de vazamento comuns com exemplos de código reais.”,
“url”: “https://techpulsesite.com/how-to-debug-memory-leaks-in-node-js-com-pt/”,
“datePublished”: “2026-06-28T16:35:00+00:00”,
“dateModified”: “2026-06-29T04:14:14+00:00”,
“author”: {
“@type”: “Organization”,
“name”: “TechPulse Editorial Team”,
“url”: “https://techpulsesite.com”
},
“publisher”: {
“@type”: “Organization”,
“name”: “TechPulse”,
“url”: “https://techpulsesite.com”
},
“inLanguage”: “pt”
}
{
“@context”: “https://schema.org”,
“@type”: “TechArticle”,
“headline”: “Como depurar vazamentos de memória em Node.js: guia passo a passo completo 2026”,
“description”: “Diagnosticar e corrigir vazamentos de memória do Node.js usando Chrome DevTools, clinic.js e sinalizador –inspect. Abrange padrões de vazamento comuns com exemplos de código reais.”,
“url”: “https://techpulsesite.com/how-to-debug-memory-leaks-in-node-js-com-pt/”,
“datePublished”: “2026-06-28T16:35:00+00:00”,
“dateModified”: “2026-06-28T18:23:22+00:00”,
“author”: {
“@type”: “Organization”,
“name”: “TechPulse Editorial Team”,
“url”: “https://techpulsesite.com”
},
“publisher”: {
“@type”: “Organization”,
“name”: “TechPulse”,
“url”: “https://techpulsesite.com”
},
“inLanguage”: “pt”
}
Um Node.jsvazamento de memória faz com que seu processo consuma gradualmente mais RAM até travar comFATAL ERROR: Reached heap limit ou fica muito lento para atender solicitações. Na produção, isso geralmente se manifesta como reinicializações semanais do servidor ou tempos de resposta degradantes. Veja como encontrá-los e corrigi-los.
📋 Table of Contents
- O que é um vazamento de memória no Node.js?
- Etapa 1: confirme se há vazamento de memória
- Etapa 2: Use –inspect + Chrome DevTools
- Etapa 3: Use clinic.js para diagnóstico automático
- Padrão de vazamento comum 1: ouvintes de eventos não removidos
- Padrão de vazamento comum 2: cache ou mapa ilimitado
- Padrão de vazamento comum 3: fechamentos capturando objetos grandes
- Padrão de vazamento comum 4: setInterval sem clearInterval
- Etapa 4: Análise de Heap Dump com heapdump
- Perguntas Frequentes
- Conclusão
O que é um vazamento de memória no Node.js?
Um vazamento de memória ocorre quando os objetos são alocados na memória, mas nunca são liberados — porque algo ainda mantém uma referência a eles, impedindo a coleta de lixo. Causas comuns: variáveis globais acumulando dados, ouvintes de eventos nunca removidos, encerramentos que capturam objetos grandes, caches que crescem ilimitadamente e retornos de chamada de temporizador contendo referências a objetos.
Etapa 1: confirme se há vazamento de memória
// Monitor memory usage in your application
function logMemory() {
const used = process.memoryUsage();
console.log({
heapUsed: `${Math.round(used.heapUsed / 1024 / 1024)}MB`,
heapTotal: `${Math.round(used.heapTotal / 1024 / 1024)}MB`,
rss: `${Math.round(used.rss / 1024 / 1024)}MB`,
external: `${Math.round(used.external / 1024 / 1024)}MB`,
});
}
setInterval(logMemory, 5000); // log every 5 seconds under load
Execute testes de carga e observe os números. SeheapUsed cresce continuamente e nunca cai após os ciclos de GC, há um vazamento.
Etapa 2: Use –inspect + Chrome DevTools
# Start Node with inspector
node --inspect app.js
# or for existing process
kill -USR1 <PID>
Abra o Chrome e navegue atéchrome://inspect. Clique em “Abrir DevTools dedicados para Node”. Na guia Memória, tire um instantâneo de heap, gere carga, aguarde 60 segundos e tire outro instantâneo. Compare-os:
No segundo instantâneo, selecione “Comparação” no menu suspenso. Classifique por “Tamanho Delta” – os objetos que crescem mais rapidamente são os candidatos a vazamento.
Etapa 3: Use clinic.js para diagnóstico automático
npm install -g clinic
# Run your app under clinic
clinic doctor -- node app.js
# More detailed heap analysis
clinic heapprofiler -- node app.js
# Flame graph for CPU + memory
clinic flame -- node app.js
Clinic gera um relatório HTML mostrando o crescimento da memória ao longo do tempo, identifica intervalos problemáticos e muitas vezes aponta diretamente para o padrão de código vazado.
Padrão de vazamento comum 1: ouvintes de eventos não removidos
// 🐛 Bug: listener added but never removed
class DataProcessor {
constructor(emitter) {
emitter.on('data', this.processData.bind(this));
// When DataProcessor is destroyed, emitter still holds reference
// → DataProcessor and its data are never GC'd
}
}
// ✅ Fix: remove listener when done
class DataProcessor {
constructor(emitter) {
this.emitter = emitter;
this.handler = this.processData.bind(this);
emitter.on('data', this.handler);
}
destroy() {
this.emitter.off('data', this.handler); // cleanup
}
}
// Check for listener leaks (Node warns at 11+ listeners)
emitter.setMaxListeners(20); // raise limit if legitimately needed
console.log(emitter.listenerCount('data')); // monitor count
Padrão de vazamento comum 2: cache ou mapa ilimitado
// 🐛 Bug: cache grows forever
const cache = new Map();
function getCachedData(key) {
if (!cache.has(key)) {
cache.set(key, fetchFromDB(key)); // never evicted
}
return cache.get(key);
}
// ✅ Fix: bounded LRU cache
const LRU = require('lru-cache');
const cache = new LRU({ max: 1000, ttl: 1000 * 60 * 5 }); // 5-min TTL, max 1000 entries
// Or simple manual TTL approach
const cache = new Map();
function getCachedData(key) {
const entry = cache.get(key);
if (entry && Date.now() - entry.time < 300000) {
return entry.data;
}
const data = fetchFromDB(key);
cache.set(key, { data, time: Date.now() });
// Evict old entries periodically
if (cache.size > 1000) cache.delete(cache.keys().next().value);
return data;
}
Padrão de vazamento comum 3: fechamentos capturando objetos grandes
// 🐛 Bug: closure keeps large data alive
function processLargeFile(data) {
const hugeBuffer = Buffer.alloc(100 * 1024 * 1024); // 100MB
hugeBuffer.copy(data);
return function processChunk(chunk) {
// This closure captures hugeBuffer — stays in memory as long as
// processChunk function exists, even if we only need one small field
return hugeBuffer.slice(0, 10);
};
}
// ✅ Fix: extract only what you need before creating closure
function processLargeFile(data) {
const hugeBuffer = Buffer.alloc(100 * 1024 * 1024);
hugeBuffer.copy(data);
const needed = hugeBuffer.slice(0, 10); // extract needed data
// hugeBuffer can now be GC'd — closure only captures 'needed'
return function processChunk(chunk) {
return needed;
};
}
Padrão de vazamento comum 4: setInterval sem clearInterval
// 🐛 Bug: interval keeps closure alive forever
function startWorker(data) {
const interval = setInterval(() => {
process(data); // data never released because interval holds it
}, 1000);
// interval never cleared when worker is "stopped"
}
// ✅ Fix: always clear intervals
function startWorker(data) {
const interval = setInterval(() => {
process(data);
}, 1000);
return function stop() {
clearInterval(interval); // release the closure reference
};
}
Etapa 4: Análise de Heap Dump com heapdump
npm install heapdump
// In your app — trigger a dump on SIGUSR2
const heapdump = require('heapdump');
process.on('SIGUSR2', () => {
heapdump.writeSnapshot((err, filename) => {
console.log('Heap snapshot written to', filename);
});
});
// Trigger from terminal
kill -USR2 <PID>
Abra o arquivo .heapsnapshot no Chrome DevTools (guia Memória → Carregar → Selecionar arquivo). Filtre por objetos que você suspeita. Procure objetos com alto “Tamanho Retido” – essa é a memória mantida viva por esse objeto.
Perguntas Frequentes
P: Qual é a diferença entre heapUsed e RSS?
A: heapUsed é a memória heap JavaScript V8. RSS (Resident Set Size) é a memória total do processo, incluindo buffers nativos, código e heap. Um RSS crescente sem aumentar o heapUsed sugere um vazamento de módulo nativo.
P: Posso forçar o teste da coleta de lixo?
R: Sim:node --expose-gc app.js então ligueglobal.gc(). Se a memória cair significativamente após a GC manual, mas crescer novamente, você confirmou um vazamento de produção.
P: Como detecto vazamentos na produção?
R: Use ferramentas APM: Datadog, New Relic ou Elastic APM monitoram o crescimento do heap ao longo do tempo. Defina alertas com 80% de uso de heap. Considere também--max-old-space-size=512 para limitar o heap e falhar rapidamente, em vez de degradação lenta.
P: WeakMap/WeakRef é útil para prevenir vazamentos?
R: Sim. WeakMap eWeakSet mantenha referências fracas — se o objeto-chave não tiver outras referências, ele será elegível para GC mesmo que seja uma chave em um WeakMap. Útil para armazenar em cache metadados sobre objetos sem impedir sua coleta.
P: Qual é um bom tamanho máximo de heap para Node.js?
R: O padrão é ~1,5 GB (64 bits). Defina explicitamente com--max-old-space-size=2048 (2GB). Dimensione para 70-80% da RAM disponível, deixando espaço para o sistema operacional e outros processos.
Conclusão
Vazamentos de memória do Node.js são diagnosticáveis e corrigíveis com as ferramentas certas. O fluxo de trabalho:confirme o vazamento com registro de memória → isole com instantâneos de heap do Chrome DevTools → identifique o padrão (ouvinte, cache, fechamento, cronômetro) → corrija e verifique. Os quatro padrões neste guia são responsáveis por 90% dos vazamentos de memória de produção. Em caso de dúvida, clinic.js indicará a direção certa em poucos minutos.
🔗 Share this article
✍️ Leave a Comment