¿Qué son las Fugas de Memoria?
Las fugas de memoria ocurren cuando las aplicaciones asignan memoria pero no la liberan, causando que el consumo crezca con el tiempo hasta agotar recursos del sistema.
La detección de fugas de memoria es una parte crítica de las pruebas de rendimiento de APIs y aplicaciones. Complementa estas pruebas con una estrategia de testing continuo para detectar regresiones de memoria temprano, e integra herramientas de detección en tu pipeline CI/CD. Para aplicaciones móviles, nuestra guía de pruebas móviles cubre técnicas específicas de profiling de memoria.
Síntomas Comunes
- Uso memoria creciente en el tiempo
- Ralentización aplicación tras uso extendido
- Errores Out of Memory (OOM)
- Pausas garbage collection
- Inestabilidad sistema
Fugas de Memoria JavaScript
1. Nodos DOM Desvinculados
// Fuga memoria - nodos DOM desvinculados
let elements = [];
function createElements() {
for (let i = 0; i < 1000; i++) {
let div = document.createElement('div');
elements.push(div); // Almacenado pero nunca adjuntado
}
}
// Corregido
const container = document.getElementById('container');
for (let i = 0; i < 1000; i++) {
container.appendChild(document.createElement('div'));
}
elements = []; // Limpiar referencias
2. Event Listeners
// Fuga - listeners no removidos
function setupButton() {
const button = document.getElementById('myButton');
button.addEventListener('click', function heavyHandler() {
const largeData = new Array(1000000).fill('data');
});
}
// Corregido - remover listeners
function setupButtonFixed() {
const button = document.getElementById('myButton');
const handler = () => { /* ... */ };
button.addEventListener('click', handler);
return () => button.removeEventListener('click', handler);
}
DevTools Navegador
Chrome DevTools
// 1. Tomar heap snapshot
// DevTools → Memory → Heap snapshot → Take snapshot
// 2. Comparar snapshots
// Snapshot 1: Estado inicial
// Realizar acciones
// Snapshot 2: Después acciones
// Comparar para encontrar objetos retenidos
Node.js Detección Fugas
# Usar clinic
npm install -g clinic
clinic doctor -- node app.js
# Generar carga
ab -n 10000 -c 100 http://localhost:3000/
Testing Automatizado
// Puppeteer memory testing
const puppeteer = require('puppeteer');
async function testMemoryLeaks() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const measurements = [];
for (let i = 0; i < 50; i++) {
await page.click('#button');
const memory = await page.evaluate(() =>
performance.memory.usedJSHeapSize
);
measurements.push(memory);
}
const growth = measurements[49] - measurements[0];
if (growth > 50 * 1024 * 1024) {
console.error('Memory leak detected!');
}
await browser.close();
}
Mejores Prácticas
- [ ] Remover event listeners en cleanup
- [ ] Limpiar todos intervals/timeouts
- [ ] Usar WeakMap para caching
- [ ] Limpiar nodos DOM desvinculados
- [ ] Implementar límites tamaño caches
Conclusión
La detección de fugas de memoria es crítica para estabilidad y rendimiento. Usar herramientas apropiadas, implementar tests automatizados y seguir mejores prácticas previene fugas antes de impactar usuarios.
Documentacion Relacionada
- Pruebas de Rendimiento de APIs - Complementa la detección de fugas con pruebas de rendimiento completas
- Testing Continuo en DevOps - Automatiza la detección de fugas de memoria en cada despliegue
- Optimización de Pipelines CI/CD para Equipos QA - Integra herramientas de profiling en tu pipeline
- Pruebas Móviles en 2025: iOS, Android y Más Allá - Técnicas de detección de fugas para aplicaciones móviles
- Guía Completa de Playwright - Usa Playwright para pruebas automatizadas de memoria en aplicaciones web