¿Cómo encontrar fugas de memoria JS?

8 minutos de lectura

Avatar de usuario de Jens Peters
Jens Peters

He tenido problemas con el generador de perfiles de montón en cromo, pero es muy confuso. Especialmente si hay bibliotecas minimizadas dentro. Pero incluso las vistas de DOMElements, elementos que no se pueden eliminar, se presentan de forma poco clara.

¿Hay algún consejo sobre cómo usar el volcado de pila en Chrome para encontrar el código JS que conduce a fugas de memoria, código que GC no puede limpiar… y cómo encontrar elementos que interfieren incluso si se eliminan de dom?

En otras palabras, ¿cómo leer correctamente el volcado de pila en Chrome? ¿Vista de dominadores? ¿Comparación?

  • A partir de 2019, ¿algún contenido más reciente?

    – t3__rry

    11 de febrero de 2019 a las 16:35


Avatar de usuario de HannesH
HannesH

Chrome ahora ofrece herramientas mucho mejores para encontrar fugas de memoria que en el momento de la mayoría de las respuestas.

Aquí está para encontrar pérdidas de memoria en javascript con un navegador Chrome reciente:

  1. Prensa F12 para abrir las herramientas de desarrollo e ir a la Ficha Memoria.

Herramientas para desarrolladores de Chrome: pestaña Memoria

  1. Elija una característica o una parte de su aplicación que desee inspeccionar en busca de fugas. Por ejemplo, cuando se abre y se vuelve a cerrar un cuadro de diálogo, se debe liberar la memoria utilizada por él.

  2. Realice la acción (por ejemplo, abrir un cuadro de diálogo) que desea verificar si hay fugas de memoria una vez, para que se puedan cargar los posibles servicios globales. Esto evita que estos objetos, que se conservan intencionalmente, se muestren como fugas.

  3. Ahora selecciona Cronología de asignación de registros y presiona comienzo. Repita la acción que desea verificar en busca de fugas varias veces. Entonces, por ejemplo, abra un cuadro de diálogo, ciérrelo y repita. Mientras haces esto, Chrome dibuja la línea de tiempo con barras parcialmente grises o azules. Por lo general, verá una barra por cada vez que realizó la acción en su página. Cuando la barra de varias iteraciones anteriores de la acción permanece parcialmente azul, generalmente significa que hay una pérdida de memoria. La parte azul de la barra representa la memoria que se asignó en este momento y aún no se ha vuelto a liberar. Detenga la grabación presionando el punto rojo en la parte superior izquierda de las herramientas de desarrollo.

Línea de tiempo de la memoria

  1. Cuando vea posibles fugas, debe inspeccionar esta parte de la línea de tiempo para encontrar la fuente. Seleccione una parte de la línea de tiempo que sea unas pocas iteraciones de sus acciones en el pasado. Y Chrome mostrará una lista de tipos de objetos que todavía están presentes en la memoria. los tamaño retenido columna le da una impresión de cuánta memoria se utiliza todavía. Busque uno de los tipos de objeto y seleccione un objeto. Si lo hace, la lista de retenedores aparecerá a continuación.

Lista de retenedores

  1. La lista de retenedores muestra los objetos “principales” que hacen referencia al objeto seleccionado. Ahora debe mirar los retenedores y su código para comprender por qué no se ha liberado la memoria. Por ejemplo en la imagen se ve el objeto del tipo scope. La segunda línea dice que el ámbito es “contexto en initFormat()”. El problema era que initFormat era un detector de eventos que no se desataba después de dejar un diálogo.

  2. Después de arreglar su código, compruebe si el problema se ha resuelto. Actualice la página y repita los pasos 3 a 6 nuevamente. Si nunca antes ha comprobado si hay fugas de memoria, no es improbable que encuentre múltiples problemas.

Consejos adicionales:

  • A veces hay cachés que retienen una parte de la memoria. Por lo general, puedes ignorarlos.
  • cuando ves el HTMLDivElement u otros elementos DOM en la lista de tipos de objetos, eche un vistazo. Si los objetos de esta lista están resaltados en rojo, significa que ya no están presentes en su página. Esto significa que deben ser una referencia en algún lugar del código. Es posible que haya olvidado desvincular un detector de eventos.
  • Lea acerca de las fugas de memoria en generalpara que puedas identificarlos más rápido en tu código.

  • ¿Por qué dices que los cachés se pueden ignorar? ¿Son imposibles de eliminar?

    – icanfathom

    14/03/2018 a las 16:29

  • Me refiero a que los cachés se mantienen intencionalmente en la memoria, porque se supone que le brindan beneficios de rendimiento. Y, por supuesto, una implementación de caché útil debería devolver la memoria después de un tiempo. Pero si el caché tiene algún error o nunca devuelve la memoria, supongo que es una pérdida de memoria. Escribí que los cachés generalmente se pueden ignorar, porque en mi caso, el caché del elemento jQuery contenía algo de memoria. Primero pensé que era una fuga, pero me di cuenta de que la memoria se había liberado después de un tiempo.

    – HannesH

    15/03/2018 a las 21:39


  • @ MrJingles87 … una pregunta ingenua. ¿Sabe si puedo almacenar el montón de aplicaciones o secuencias de comandos de JavaScript usando el lenguaje JavaScript … var heap = store(...); //or store(this);

    – Desarrollador ingenuo

    12 de noviembre de 2018 a las 16:12

  • @NaiveDeveloper: lo siento, no lo sé

    – HannesH

    19 de noviembre de 2018 a las 16:47

En las herramientas para desarrolladores de Chrome, hay una línea de tiempo – pestaña Memoria:

ingrese la descripción de la imagen aquí

Podemos observar la memoria ocupada por él.

También está Profiles – Memory, donde podemos tomar una instantánea y ver qué hay dentro. Las instantáneas se pueden comparar entre sí:

ingrese la descripción de la imagen aquí

La mayoría de las veces, no te dice nada. Pero al menos puede ver qué objetos se están acumulando y probablemente la estructura de la fuga.

Otra forma es usando 'Task Manager'
aquí hay un artículo sobre esto:

http://www.javascriptkit.com/javatutors/closuresleak/

avatar de usuario de adrianp
adrianp

Google abrió una herramienta de código abierto para este propósito, buscador-de-fugas-para-javascript. También propusieron un método llamado técnica de las tres instantáneas (ver también una breve descripción en Este artículo).

Primer párrafo del enlace del buscador de fugas

Nota: ¡jsleakcheck ya no es compatible! Estaba trabajando en contra de un protocolo de herramientas de desarrollo no oficial e inestable para tomar instantáneas de montón. Se está trabajando en el protocolo y no es lo suficientemente estable como para poder mantener jsleakcheck funcionando con varias versiones de Chrome. Además, se eliminó una herramienta de compatibilidad de nivel inferior, remote_inspector_client.py, que jsleakcheck estaba usando para comunicarse con Dev Tools.

  • La página de búsqueda de fugas para javascript ahora tiene un gran aviso en la parte superior que dice que ya no es compatible.

    – Burhan Alí

    7 de agosto de 2014 a las 14:02

  • Un nuevo enlace estaría bien.

    – Scheintod

    12 de enero de 2015 a las 20:04

Encontré este artículo muy revelador:

http://addyosmani.com/blog/taming-the-unicorn-easing-javascript-memory-profiling-in-devtools/

Cubre ampliamente las herramientas de desarrollo de Chrome y explica muy bien cómo actuar cuando su aplicación parece tener problemas de memoria.

Avatar de usuario de Sunny SM
Soleado SM

Citado de Kit JavaScript:

Si está desarrollando objetos de secuencias de comandos reutilizables del lado del cliente, tarde o temprano descubrirá fugas de memoria. Lo más probable es que su navegador absorba la memoria como una esponja y difícilmente podrá encontrar una razón por la cual la capacidad de respuesta de su encantadora navegación DHTML disminuya severamente después de visitar un par de páginas dentro de su sitio.

Un desarrollador de Microsoft, Justin Rogers, ha descrito los patrones de fuga de IE en su excelente articulo (de web.archive.org).

En este artículo, revisaremos esos patrones desde una perspectiva ligeramente diferente y los respaldaremos con diagramas y gráficos de uso de memoria. También presentaremos varios escenarios de fugas más sutiles. Antes de comenzar, le recomiendo encarecidamente que lea ese artículo si aún no lo ha leído.

¿Por qué se pierde la memoria?

El problema de la fuga de memoria no se limita solo a Internet Explorer. Casi cualquier navegador (incluidos, entre otros, Mozilla, Netscape y Opera) perderá memoria si proporciona las condiciones adecuadas (y no es tan difícil hacerlo, como veremos en breve). Pero (en mi humilde opinión, ymmv, etc.) Internet Explorer es el rey de las filtraciones.

No me malinterpretes. No pertenezco a la multitud que grita “Oye, IE tiene pérdidas de memoria, mira esta nueva herramienta [link-to-tool] y compruébelo usted mismo”. Hablemos de lo malo que es Internet Explorer y cubramos todas las fallas en otros navegadores”.

Cada navegador tiene sus propias fortalezas y debilidades. Por ejemplo, Mozilla consume demasiada memoria en el arranque inicial, no es bueno en las operaciones de cadenas y matrices; Opera puede bloquearse si escribe un script DHTML ridículamente complejo que confunde su motor de renderizado.

Aunque nos centraremos en las situaciones de pérdida de memoria en Internet Explorer, esta discusión es igualmente aplicable a otros navegadores.

sigue leyendo…

avatar de usuario de sdespont
sdespont

Aquí hay una muy buena publicación sobre cómo encontrar fugas de memoria usando las herramientas de desarrollo de Google: http://gent.ilcore.com/2011/08/finding-memory-leaks.html

Aquí hay otra buena página web sobre eso: http://javascript.crockford.com/memory/leak.html

Avatar de usuario de Yves M.
yves m

no veo mencionado window.performance.memoryque le brinda la capacidad en tiempo de ejecución para monitorear y tomar medidas en función del uso de la memoria.

window.performance.memory:

MemoryInfo {
  totalJSHeapSize: 7084834,
  usedJSHeapSize: 6486770,
  jsHeapSizeLimit: 4294705152
}

Para un porcentaje práctico, use esto:

window.performance.memory.usedJSHeapSize / window.performance.memory.jsHeapSizeLimit

https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory

  • FYI, esto parece ser solo para Chrome.

    – TVE

    27 de junio de 2021 a las 14:57

¿Ha sido útil esta solución?