Registro de instantáneas de montón mediante la herramienta Memoria ("Tipo de generación de perfiles instantánea del montón")

Use el generador de perfiles del montón en la herramienta Memoria para hacer lo siguiente:

  • Registre instantáneas de montón de JavaScript (montón de JS).
  • Analice los gráficos de memoria.
  • Comparar instantáneas.
  • Busque pérdidas de memoria.

El generador de perfiles de montón de DevTools muestra la distribución de memoria que usan los objetos JavaScript y los nodos DOM relacionados en la página web representada.

Tomar una instantánea

  1. Abra la página web que desea analizar. Por ejemplo, abra la página de demostración Objetos dispersos en una nueva ventana o pestaña.

  2. Para abrir DevTools, haga clic con el botón derecho en la página web y, a continuación, seleccione Inspeccionar. O bien, presione Ctrl+Mayús+I (Windows, Linux) o Comando+Opción+I (macOS). Se abre DevTools.

  3. En DevTools, en la barra de actividad, seleccione la pestaña Memoria . Si esa pestaña no está visible, haga clic en el botón Más herramientas (icono Más herramientas).

  4. En la sección Seleccionar tipo de generación de perfiles , seleccione el botón de opción Instantánea de montón .

  5. En Seleccionar instancia de máquina virtual JavaScript, seleccione la máquina virtual de JavaScript de la que desea generar perfiles.

  6. Haga clic en el botón Tomar instantánea :

La herramienta Memoria, la opción Instantánea de montón está seleccionada y el botón Tomar instantánea está resaltado.

Una vez que la instantánea del montón recién registrada se ha cargado en DevTools y se ha analizado, se muestra la instantánea y aparece una nueva entrada en la barra lateral Perfiles en Instantáneas del montón:

Tamaño total de objetos accesibles

El número debajo del nuevo elemento de barra lateral muestra el tamaño total de los objetos JavaScript accesibles. Para obtener más información sobre los tamaños de objetos en la instantánea del montón, consulte Tamaños y distancias de objetos en Terminología de memoria.

La instantánea solo muestra los objetos del gráfico de memoria a los que se puede acceder desde el objeto global. La toma de una instantánea siempre comienza con una recolección de elementos no utilizados.

Tomar otra instantánea

Para tomar otra instantánea cuando ya se muestre una en la herramienta Memoria , en la barra lateral, haga clic en Perfiles encima de la instantánea existente:

Botón Perfiles para tomar otra instantánea

Borrar instantáneas

Para borrar todas las instantáneas de la herramienta Memoria , haga clic en el icono Borrar todos los perfiles (icono Borrar):

Eliminación de instantáneas

Visualización de instantáneas

Las instantáneas de montón se pueden ver de varias maneras diferentes en la herramienta Memoria . Cada forma de ver una instantánea de montón en la interfaz de usuario corresponde a una tarea diferente:

Vista Contenido Se usa para
Resumen Muestra objetos agrupados por su nombre de constructor. Buscar objetos y la memoria que usan, en función de los tipos que se agrupan por nombre de constructor. Útil para el seguimiento de fugas de DOM.
Comparación Muestra las diferencias entre dos instantáneas. Comparación de dos (o más) instantáneas de memoria antes y después de una operación. Inspeccionar el delta en la memoria liberada e inspeccionar el recuento de referencias le ayuda a confirmar la presencia y la causa de una pérdida de memoria, y ayuda a determinar su causa.
Contención Permite la exploración del contenido del montón. Proporciona una mejor vista de la estructura de objetos, lo que ayuda a analizar los objetos a los que se hace referencia en el espacio de nombres global (ventana) para averiguar lo que mantiene los objetos alrededor. Úsela para analizar cierres y profundizar en los objetos a un nivel bajo.

Para cambiar entre vistas, use la lista desplegable en la parte superior de la herramienta Memoria :

Cambiar selector de vistas

Elementos omitidos de instantáneas de montón

Las propiedades que se implementan mediante captadores que ejecutan código nativo no se capturan en la instantánea del montón, ya que estas propiedades no se almacenan en el montón de JavaScript.

Los valores que no son de cadena, como números, no se capturan.

Vista de resumen

La vista Resumen de la herramienta Memoria muestra lo siguiente:

  • Grupos de constructores de objetos.
  • Nombres de categoría especiales, como (matriz), (código compilado) o una lista de propiedades como {foo, bar, baz}.

Inicialmente, se abre una instantánea del montón en la vista Resumen , que muestra una lista de constructores:

Vista de resumen

Cada constructor de la lista se puede expandir para mostrar los objetos que se crearon instancias mediante ese constructor.

Para cada constructor de la lista, la vista Resumen también muestra un número como ×123, que indica el número total de objetos creados con el constructor. La vista Resumen también muestra las columnas siguientes:

Nombre de columna Descripción
Distancia Muestra la distancia a la raíz mediante la ruta de acceso más corta de los nodos. Consulte Terminología de distancia en memoria.
Tamaño superficial Muestra la suma de tamaños superficiales de todos los objetos creados por una función de constructor determinada. El tamaño superficial es el tamaño del montón de JavaScript que contiene directamente un objeto. El tamaño superficial de un objeto suele ser pequeño, ya que un objeto De JavaScript a menudo solo almacena su descripción del objeto, no los valores, en la memoria que contiene directamente el objeto. La mayoría de los objetos JavaScript almacenan sus valores en un almacén de respaldo que se encuentra en otra parte del montón de JavaScript y solo exponen un pequeño objeto contenedor en la parte del montón de JavaScript que es propiedad directa del objeto. Consulte Tamaño superficial en Terminología de memoria.
Tamaño retenido Muestra el tamaño máximo retenido entre el mismo conjunto de objetos. El tamaño de la memoria que puede liberar después de eliminar un objeto (y que ya no se pueda acceder a los dependientes) se denomina tamaño retenido. Consulte Tamaño retenido en terminología de memoria.

Después de expandir un constructor en la vista Resumen , se muestran todas las instancias del constructor. Para cada instancia, los tamaños superficiales y retenidos se muestran en las columnas correspondientes. El número después del @ carácter es el identificador único del objeto, lo que permite comparar las instantáneas del montón por objeto.

Entradas del constructor

En la vista Resumen de la herramienta Memoria se enumeran los grupos de constructores de objetos:

Grupos de constructores

Los grupos de constructores de la vista Resumen pueden ser funciones integradas como Array o Object, o bien pueden ser funciones definidas en su propio código.

Para mostrar la lista de objetos a los que se ha creado una instancia de un constructor determinado, expanda el grupo de constructores.

Nombres de categoría especiales

La vista Resumen de la herramienta Memoria incluye los siguientes nombres de categoría especiales, que no se basan en constructores. La mayoría de estos nombres de categoría se muestran entre paréntesis.

Nombre de categoría Descripción
(matriz) Varios objetos internos similares a una matriz que no se corresponden directamente con objetos visibles desde JavaScript, como el contenido de matrices de JavaScript o las propiedades con nombre de objetos JavaScript.
(código compilado) Datos internos que V8 (motor de JavaScript de Microsoft Edge) necesita para ejecutar funciones definidas por JavaScript o WebAssembly. V8 administra automáticamente el uso de memoria en esta categoría: si una función se ejecuta muchas veces, V8 usa más memoria para esa función para que la función se ejecute más rápido. Si una función no se ha ejecutado en un tiempo, V8 podría eliminar los datos internos de esa función.
(cadena concatenada) Cuando dos cadenas se concatenan juntas, como cuando se usa el operador JavaScript + , V8 puede optar por representar el resultado internamente como una cadena concatenada. En lugar de copiar todos los caracteres de las dos cadenas en una nueva cadena, V8 crea un objeto pequeño que apunta a las dos cadenas.
(forma de objeto) Información sobre objetos, como el número de propiedades que tienen y una referencia a sus prototipos, que V8 mantiene internamente cuando se crean y actualizan objetos. Esto permite que V8 represente de forma eficaz objetos con las mismas propiedades.
(cadena segmentada) Al crear una subcadena, como cuando se usa el método JavaScript substring , V8 puede optar por crear un objeto de cadena segmentada en lugar de copiar todos los caracteres pertinentes de la cadena original. Este nuevo objeto contiene un puntero a la cadena original y describe qué intervalo de caracteres de la cadena original se va a usar.
(sistema) Varios objetos internos que aún no se han clasificado de forma más significativa.
{foo, bar, baz} Objetos JavaScript sin formato clasificados por interfaz (lista de propiedades), entre llaves. Los objetos JavaScript sin formato no aparecen en una categoría denominada Object, sino que se representan mediante nombres y categorías que se basan en las propiedades que contiene el objeto, como {foo, bar, baz}.
InternalNode Objetos asignados fuera de V8, como objetos de C++ definidos por Blink, el motor de representación de Microsoft Edge.
system/Context Variables locales desde un ámbito de JavaScript al que puede acceder alguna función anidada. Cada instancia de función contiene un puntero interno al contexto en el que se ejecuta, de modo que pueda acceder a esas variables.

Vista de comparación

Para buscar objetos filtrados, compare varias instantáneas entre sí. En una aplicación web, normalmente, realizar una acción y, a continuación, la acción inversa no debería dar lugar a más objetos en la memoria. Por ejemplo, al abrir un documento y, a continuación, cerrarlo, el número de objetos en memoria debe ser el mismo que antes de abrir el documento.

Para comprobar que ciertas operaciones no crean pérdidas:

  1. Tome una instantánea del montón antes de realizar una operación.

  2. Realice la operación. Es decir, interactuar con la página de alguna manera que podría estar causando una fuga.

  3. Realice la operación inversa. Es decir, hacer la interacción opuesta y repetirla varias veces.

  4. Tome una segunda instantánea del montón.

  5. En la segunda instantánea del montón, cambie la vista a Comparación y compárela con la instantánea 1.

En la vista Comparación , se muestra la diferencia entre dos instantáneas:

Vista de comparación

Al expandir un constructor en la lista, se muestran las instancias de objeto agregadas y eliminadas.

Vista de contención

La vista Contención permite ver dentro de los cierres de función, observar objetos internos de máquina virtual (VM) que componen los objetos de JavaScript y comprender cuánta memoria usa la aplicación en un nivel muy bajo:

Vista de contención

La vista Contención muestra los siguientes tipos de objetos:

Puntos de entrada de la vista de contención Descripción
Objetos DOMWindow Objetos globales para código JavaScript.
Raíces de GC Raíces de GC usadas por el recolector de elementos no utilizados de la máquina virtual JavaScript. Las raíces de GC se componen de mapas de objetos integrados, tablas de símbolos, pilas de subprocesos de máquina virtual, cachés de compilación, ámbitos de identificador y identificadores globales.
Objetos nativos Objetos creados por el explorador, como nodos DOM y reglas CSS, que se muestran en la máquina virtual JavaScript para permitir la automatización.

Sección Retenedores

La sección Retenedores se muestra en la parte inferior de la herramienta Memoria y muestra todos los objetos que apuntan al objeto seleccionado. La sección Retenedores se actualiza al seleccionar un objeto diferente en la vista Resumen, Contención o Comparación .

En la captura de pantalla siguiente, se seleccionó un objeto de cadena en la vista Resumen y la sección Retainers muestra que la cadena se conserva mediante la x propiedad de una instancia de la Item clase , que se encuentra en el example-03.js archivo :

Sección Retenedores

Ocultar ciclos

En la sección Retenes , al analizar los objetos que conservan el objeto seleccionado, es posible que encuentre ciclos. Los ciclos se producen cuando el mismo objeto aparece más de una vez en la ruta de acceso del retención del objeto seleccionado. En la sección Retenedores , se indica que un objeto con ciclo está atenuado.

Para simplificar la ruta de acceso del retenedor, oculte los ciclos en la sección Retenedores haciendo clic en el menú desplegable Filtrar bordes y, a continuación, seleccionando Ocultar ciclo:

El menú desplegable Filtrar bordes de la sección Retenedores,

Ocultar nodos internos

Los nodos internos son objetos específicos de V8 (el motor de JavaScript en Microsoft Edge).

Para ocultar los nodos internos de la sección Retenedores , en el menú desplegable Bordes de filtro , seleccione Ocultar interno.

Filtrar instantáneas de montón por tipos de nodo

Use filtros para centrarse en partes específicas de una instantánea de montón. Al examinar todos los objetos de una instantánea de montón en la herramienta Memoria , puede ser difícil centrarse en objetos específicos o conservar rutas de acceso.

Para centrarse solo en tipos específicos de nodos, use el filtro Tipos de nodo , en la esquina superior derecha. Por ejemplo, para ver solo las matrices y los objetos de cadena en la instantánea del montón:

  1. Para abrir el filtro Tipos de nodo , haga clic en Predeterminado en la esquina superior derecha.

  2. Seleccione las entradas Matriz y Cadena .

    La instantánea del montón se actualiza para mostrar solo los objetos de matriz y cadena:

    Tipos de nodo en una instantánea de montón en la herramienta Memoria

Búsqueda de un objeto específico

Para buscar un objeto en el montón recopilado, puede buscar mediante Ctrl+F y proporcionar el identificador de objeto.

Descubrir fugas de DOM

La herramienta Memoria tiene la capacidad de mostrar las dependencias bidireccionales que a veces existen entre objetos nativos del explorador (nodos DOM, reglas CSS) y objetos JavaScript. Esto ayuda a detectar fugas de memoria que se producen debido a nodos DOM olvidados y desasociados que permanecen en la memoria.

Para los elementos desasociados, vea también Buscar pérdidas de memoria de árbol DOM ("Instantánea de montón" tipo > de generación de perfiles Desasociada) a continuación.

Tenga en cuenta el siguiente árbol DOM:

Subárboles DOM

En el ejemplo de código siguiente se crean las variables treeRef de JavaScript y leafRef, que hacen referencia a dos de los nodos DOM del árbol:

// Get a reference to the #tree element.
const treeRef = document.querySelector("#tree");

// Get a reference to the #leaf element,
// which is a descendant of the #tree element.
const leafRef = document.querySelector("#leaf");

En el ejemplo de código siguiente, el <div id="tree"> elemento se quita del árbol DOM:

// Remove the #tree element from the DOM.
document.body.removeChild(treeRef);

El <div id="tree"> elemento no se puede recopilar como elemento no utilizado porque la variable treeRef de JavaScript todavía existe. La treeRef variable hace referencia directamente al <div id="tree"> elemento . En el ejemplo de código siguiente, se nullifica la treeRef variable:

// Remove the treeRef variable.
treeRef = null;

El <div id="tree"> elemento todavía no se puede recopilar como elemento no utilizado porque la variable leafRef de JavaScript todavía existe. La leafRef.parentNode propiedad hace referencia al <div id="tree"> elemento . En el ejemplo de código siguiente, se nullifica la leafRef variable:

// Remove the leafRef variable.
leafRef = null;

En este punto, el <div id="tree"> elemento puede ser recolector de elementos no utilizados. En treeRef primer lugar, y leafRef deben anularse, para que todo el árbol DOM del <div id="tree"> elemento se recopile como elementos no utilizados.

Página web de demostración: Ejemplo 6: Fuga de nodos DOM

Para comprender dónde se pueden filtrar los nodos DOM y cómo detectar dicha pérdida, abra la página web de ejemplo Ejemplo 6: Fuga de nodos DOM en una nueva ventana o pestaña.

Página web de demostración: ejemplo 9: fugas dom mayores de lo esperado

Para ver por qué una fuga dom podría ser mayor de lo esperado, abra la página web de ejemplo Ejemplo 9: Fugas dom mayores de lo esperado en una nueva ventana o pestaña.

Análisis del impacto de los cierres en la memoria

Para analizar el impacto de los cierres en la memoria, pruebe este ejemplo:

  1. Abra la página web de demostración de Eval is evil en una nueva ventana o pestaña.

  2. Registre una instantánea del montón.

  3. En la página web representada, haga clic en el botón Cierres con eval .

  4. Registre una segunda instantánea del montón.

    En la barra lateral, el número debajo de la segunda instantánea debe ser mayor que el número debajo de la primera instantánea. Esto indica que la página web usa más memoria después de hacer clic en el botón Cierres con eval .

  5. En la segunda instantánea del montón, cambie la vista a Comparación y, a continuación, compare la segunda instantánea del montón con la primera instantánea del montón.

    La vista Comparación muestra que se crearon nuevas cadenas en la segunda instantánea del montón:

    La vista Comparación, que muestra que se crearon nuevas cadenas en la segunda instantánea

  6. En la vista Comparación, expanda el constructor (cadena).

  7. Haga clic en la primera entrada (cadena).

    La sección Retainers se actualiza y muestra que la largeStr variable conserva la cadena seleccionada en la vista Comparación .

    La largeStr entrada se expande automáticamente y muestra que la función conserva la eC variable, que es el cierre donde se define la variable:

    Sección Retainers, que muestra que la función eC conserva la cadena.

Sugerencia: Funciones de nombre para diferenciar entre cierres en una instantánea

Para distinguir fácilmente entre cierres de JavaScript en una instantánea de montón, proporcione los nombres de las funciones.

En el ejemplo siguiente se usa una función sin nombre para devolver la largeStr variable :

function createLargeClosure() {
    const largeStr = 'x'.repeat(1000000).toLowerCase();

    // This function is unnamed.
    const lC = function() {
        return largeStr;
    };

    return lC;
}

En el ejemplo siguiente se asigna un nombre a la función, lo que facilita la distinción entre cierres en la instantánea del montón:

function createLargeClosure() {
    const largeStr = 'x'.repeat(1000000).toLowerCase();

    // This function is named.
    const lC = function lC() {
        return largeStr;
    };

    return lC;
}

Guardar y exportar cadenas desde una instantánea de montón a JSON

Al tomar una instantánea de montón en la herramienta Memoria , puede exportar todos los objetos de cadena de la instantánea a un archivo JSON. En la herramienta Memoria , en la sección Constructor , haga clic en el botón Guardar todo en archivo situado junto a la (string) entrada:

Guardar todas las cadenas de una instantánea de montón en JSON

La herramienta Memoria exporta un archivo JSON que contiene todos los objetos de cadena de la instantánea del montón:

Cadenas de la instantánea del montón, en el archivo JSON

Buscar pérdidas de memoria de árbol DOM ("Instantánea de montón" tipo > de generación de perfiles Desasociada)

Una manera de buscar y mostrar todos los elementos desasociados en una página web es usar el tipo de generación de perfiles de instantáneas Montón de la herramienta Memoria y, a continuación, escribir Desasociado en el cuadro de texto Filtrar por clase, como se indica a continuación. Consulte también Herramientas para investigar los elementos desasociados en Solucionar problemas de memoria.

El código siguiente genera nodos DOM desasociados:

var detachedTree;

function create() {
    var ul = document.createElement('ul');
    for (var i = 0; i < 10; i++) {
        var li = document.createElement('li');
        ul.appendChild(li);
    }
    detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);

Este código crea un ul nodo con diez li elementos secundarios. El código hace referencia a los nodos, pero no existen en el árbol DOM, por lo que cada nodo se desasocia.

Las instantáneas de montón son una manera de identificar nodos desasociados. Una instantánea del montón muestra cómo se distribuye la memoria entre los objetos JS y los nodos DOM de la página en el momento de la instantánea.

Usar el tipo de generación de perfiles "Instantánea de montón" para buscar elementos desasociados

Para usar el tipo de generación de perfiles de instantáneas montón para buscar elementos desasociados:

  1. Abra una página web, como la página web de demostración Detached Elements, en una nueva ventana o pestaña.

  2. Haga clic con el botón derecho en la página web y, a continuación, seleccione Inspeccionar. O bien, presione Ctrl+Mayús+I (Windows, Linux) o Comando+Opción+I (macOS).

    Se abre DevTools.

  3. En DevTools, en la barra de actividad, seleccione la herramienta Memoria (icono de herramienta Memoria).

    Si esa pestaña no está visible, haga clic en el botón Más herramientas (icono Más herramientas) y, a continuación, seleccione Memoria. Se abre la herramienta Memoria :

    Abrir la herramienta Memoria

    Si no se muestra el botón de opción Instantánea del montón , ya que ya se muestra un perfil, en la parte superior izquierda, haga clic en Perfiles (icono Perfiles).

    No es necesario seleccionar el botón de opción Instantánea de montón en este momento, ya que la página web aún no ha generado ningún elemento desasociado.

    Genere mensajes, que almacenará la instancia de JavaScript de la clase Room:

  4. En la página web de demostración, haga clic en el botón Tráfico rápido .

    La página web de demostración comienza a generar mensajes y mostrarlos en la página web:

    Generación de algunos mensajes en la página web de demostración

  5. Después de mostrar algunos mensajes, haga clic en el botón Detener de la página web de demostración.

    Cada mensaje es un <div class="message"> elemento al que hace referencia la instancia de Room 1 de la Room clase . No hay ningún elemento desasociado en el árbol DOM de la página web, porque todos los elementos del mensaje están adjuntos a la instancia actual de Room 1 de la clase Room .

    Cambie a una instancia diferente de la clase Room, de modo que los elementos se desasocián:

  6. En la página web de demostración, haga clic en el botón Sala 2 , que corresponde a otra instancia de la Room clase .

    En la página web, los mensajes desaparecen:

    Vista inicial de la habitación 2

    Los mensajes generados para la instancia de Room 1 de la clase Room (<div class="message"> elementos) ya no están conectados al DOM, pero la instancia de Room 1 de la clase Room sigue haciendo referencia a ellos. Son elementos desasociados, lo que puede provocar pérdidas de memoria, a menos que la página web los vuelva a usar.

    Obtenga la lista de elementos desasociados:

  7. En DevTools, en la herramienta Memoria , haga clic en el icono Recopilar elementos no utilizados (El icono ):

    Tomar una instantánea del montón

    El explorador ejecuta la recolección de elementos no utilizados, quitando los nodos a los que ya no hace referencia un objeto JavaScript.

  8. En la herramienta Memoria , seleccione el botón de opción Instantánea de montón .

  9. Haga clic en el botón Tomar instantánea en la parte inferior de la herramienta Memoria .

    La instantánea se procesa, carga y, a continuación, se muestra en la barra lateral Perfiles , en la sección Instantáneas del montón .

  10. En el cuadro de texto Filtrar por clase , escriba desasociado:

    Filtrado de nodos desasociados y expansión de un nodo desasociado

    Se muestran los elementos DOM desasociados que no se pueden recopilar como elementos no utilizados.

    Identifique el código JavaScript que hace referencia a un elemento desasociado determinado:

  11. En la instantánea del montón, expanda un objeto desasociado, como Div desasociado <>y, a continuación, seleccione un nodo Detached <div class="message">.

    La información se muestra en el panel Retenedores de la parte inferior de la herramienta Memoria .

  12. En el panel Retenedores , haga clic en el room.js:13 vínculo de un elemento Desmontado en Sala en Matriz. Se abre la herramienta Orígenes , que muestra room.js, desplazada a la línea 13:

    Código fuente de JavaScript en la herramienta Orígenes

  13. Para inspeccionar la posible pérdida de memoria, examine el código que usa la unmounted matriz y asegúrese de que la referencia al nodo se quite cuando ya no se necesite.

  14. Para volver a la herramienta Memoria , en la barra de direcciones, seleccione la herramienta Memoria .

Para obtener más formas de ver los elementos desasociados, consulte Herramientas para investigar elementos desasociados en Solucionar problemas de memoria.

Vea también

Externo:

Nota:

Las partes de esta página son modificaciones basadas en el trabajo creado y compartido por Google y usadas según los términos descritos en la licencia internacional creative Commons Attribution 4.0. La página original se encuentra aquí y es creada por Meggin Kearney.

Licencia de Creative Commons Esta obra está licenciada bajo una Licencia Internacional Creative Commons Attribution 4.0.