Desarrollador Node.js: pregunta de entrevista
¿Cómo investigas una fuga de memoria en Node.js?
Reproduce el crecimiento con carga estable, compara heap snapshots y perfiles de asignación, revisa rutas retenidas, timers, listeners y cachés, corrige el ciclo de vida propietario y verifica que el heap se estabiliza.
Respuesta directa
Qué debe cubrir una buena respuesta
Cómo funciona
Una fuga en Node suele ser una referencia que sobrevive a su propósito: un Map que crece sin límite usado como caché, listeners de eventos añadidos por solicitud y nunca eliminados, closures capturados por temporizadores nunca cancelados, o una cadena de promesas que mantiene vivos objetos de solicitud. La investigación reproduce un crecimiento constante bajo carga estable, toma snapshots de heap con minutos de separación y los compara por tamaño retenido para ver qué constructor se acumula; el árbol de retenedores muestra entonces quién sostiene los objetos. Un perfil de línea de tiempo de asignaciones muestra dónde se crean. El arreglo cambia el ciclo de vida propietario, y la prueba es un heap que se estabiliza tras la misma prueba.
Ejemplo
Un servicio crecía 50 MB por hora; dos snapshots mostraron miles de objetos Socket retenidos, alcanzables desde un array en un plugin de métricas que añadía cada conexión y nunca la quitaba al cerrar. Eliminar la entrada en el evento close lo arregló, y ahora corre una prueba de larga duración en staging con gráfica de heap antes de cada release.
Errores frecuentes
- Reiniciar el servicio cada noche como solución permanente.
- Comparar snapshots tomados con segundos de diferencia y perseguir basura aún no recolectada.
- Añadir listeners de process dentro de un handler de solicitud.
Una estructura útil para responder
Responde desde tu propia experiencia.
No memorices un guion: usa solo ejemplos que puedas explicar con honestidad en preguntas posteriores.
Abre el espacio de trabajo de escritorio y ensaya una respuesta clara con tus propias palabras.