Compartir a través de


Formato de archivo de instantánea del montón

La investigación del uso de memoria en aplicaciones web puede ser difícil. La herramienta Memoria de DevTools permite explorar todos los objetos asignados en memoria por la aplicación web mediante una instantánea de montón. Esta información es útil para las investigaciones de rendimiento, ya que puede averiguar qué objetos consumen más memoria.

Sin embargo, a veces es posible que tenga que centrarse en partes específicas de los datos de memoria que la herramienta Memoria no muestra. En este caso, use DevTools para exportar todo el conjunto de datos de memoria como un .heapsnapshot archivo JSON.

En este artículo se describe la estructura y el contenido de .heapsnapshot los archivos JSON para que pueda crear sus propias herramientas de visualización y análisis.

Registro de una instantánea de montón

Para exportar un .heapsnapshot archivo, primero debe registrar una instantánea de montón en la herramienta Memoria , como se indica a continuación:

  1. En Microsoft Edge, vaya al sitio web desde el que desea exportar los datos.

  2. Presione Ctrl+Mayús+I (Windows, Linux) o Comando+Opción+I (macOS) para abrir Devtools.

  3. Abra la herramienta Memoria .

  4. Seleccione Instantánea de montón y, a continuación, haga clic en Tomar instantánea.

Para obtener más información, consulte Registro de instantáneas de montón mediante la herramienta Memoria ("Tipo de generación de perfiles instantánea de montón").

Exportación y visualización de un .heapsnapshot archivo

Una vez que haya grabado una instantánea del montón, puede exportarla.

  1. En la barra lateral izquierda de la herramienta Memoria , haga clic en Guardar junto al elemento de instantánea del montón que acaba de grabar.

  2. Cambie la extensión de archivo de a .json, para facilitar la apertura del archivo en un editor de .heapsnapshot texto.

  3. Abra el archivo guardado en un editor de texto, como Visual Studio Code.

  4. Para facilitar la lectura del código JSON, en Visual Studio Code, haga clic con el botón derecho en cualquier lugar del código y, a continuación, seleccione Dar formato al documento.

Por lo general, el archivo resultante .heapsnapshot es diferente cada vez que se registra y exporta una instantánea del montón. Las instantáneas de montón se generan dinámicamente, en función del contenido de la aplicación web que se está inspeccionando actualmente en DevTools.

Información general sobre el formato de .heapsnapshot archivo

La memoria usada por una aplicación web se organiza como un grafo de V8, que es el motor de JavaScript que usa Microsoft Edge. Un gráfico es un tipo de datos que se compone de nodos (puntos en el gráfico) y bordes (vínculos entre los puntos).

Los datos del .heapsnapshot archivo representan la memoria de la aplicación web que se gráfico de forma eficaz y facilita la transferencia de grupos de datos entre el proceso del explorador y DevTools. El .heapsnapshot archivo contiene una representación plana de las relaciones entre nodos y bordes, como un objeto JSON que contiene matrices de números y cadenas. El archivo tiene una .heapsnapshot extensión de nombre de archivo y contiene datos con formato JSON.

Los datos tienen dos partes principales:

  • Los metadatos, que contienen toda la información necesaria para analizar las matrices de datos que representan el gráfico de memoria.
  • Los datos de matrices, que contienen los datos reales necesarios para volver a crear el gráfico.

Actualización de esta documentación de formato de datos

El formato del .heapsnapshot archivo, como se documenta a continuación, puede cambiar a medida que evolucionan V8 y DevTools. Si encuentra una discrepancia en la documentación, proporcione comentarios en el repositorio MicrosoftDocs/edge-developer.

Esquema de los .heapsnapshot datos

Estructura de nivel superior

Los .heapsnapshot datos JSON contienen un objeto raíz que tiene las siguientes propiedades:

{
    "snapshot": {},
    "nodes": [],
    "edges": [],
    "trace_function_infos": [],
    "trace_tree": [],
    "samples": [],
    "locations": [],
    "strings": []
}
Propiedad Descripción Formato
snapshot Contiene toda la información sobre el formato de los datos del gráfico de memoria y su tamaño. Object
nodes Toda la información necesaria para volver a crear los nodos del gráfico. Para analizar estos datos, use snapshot.meta.node_types y snapshot.meta.node_fields. Array
edges Toda la información necesaria para volver a crear los bordes del gráfico. Para analizar estos datos, use snapshot.meta.edge_types y snapshot.meta.edge_fields. Array
trace_function_infos Aún no documentado Array
trace_tree Aún no documentado Array
samples Aún no documentado Array
locations Contiene información sobre la ubicación del script de los nodos. Para analizar estos datos, use snapshot.meta.location_fields con la nodes matriz . Array
strings Matriz de todas las cadenas que se conservan en la memoria. Pueden ser cualquier cadena, como cadenas definidas por el usuario o código. Array

Instantánea

{
    "snapshot": {     
        "meta": {},
        "node_count": 123,
        "edge_count": 456,
        "trace_function_count": 0
    }
    ...
}
Propiedad Descripción Formato
meta Propiedades que contienen información sobre la forma y el tamaño de cada objeto contenido en los datos del gráfico de memoria. Object
node_count Número total de nodos en el gráfico de memoria. Number
edge_count Número total de bordes en el gráfico de memoria. Number
trace_function_count Número total de funciones de seguimiento en el gráfico de memoria. Number

Metadatos de instantáneas

{
    "snapshot": {
        "meta": {
            "node_fields": [],
            "node_types": [],
            "edge_fields": [],
            "edge_types": []
        }
    }
    ...
}
Propiedad Descripción Formato
node_fields Lista de todas las propiedades necesarias para volver a crear un nodo. Array
node_types Tipos de todas las propiedades necesarias para volver a crear un nodo. El número de tipos es el mismo que el número de propiedades definidas en node_fields. Array
edge_fields Lista de todas las propiedades necesarias para volver a crear un borde. Array
edge_types Tipos de todas las propiedades necesarias para volver a crear un borde. El número de tipos es el mismo que el número de propiedades de edge_fields. Array

A continuación se muestra un ejemplo de un objeto de metadatos:

{
    "snapshot": {
        "meta": {
            "node_fields": [
                "type",
                "name",
                "id",
                "self_size",
                "edge_count",
                "trace_node_id",
                "detachedness"
            ],
            "node_types": [
                [
                    "hidden",
                    "array",
                    "string",
                    "object",
                    "code",
                    "closure",
                    "regexp",
                    "number",
                    "native",
                    "synthetic",
                    "concatenated string",
                    "sliced string",
                    "symbol",
                    "bigint",
                    "object shape"
                ],
                "string",
                "number",
                "number",
                "number",
                "number",
                "number"
            ],
            "edge_fields": [
                "type",
                "name_or_index",
                "to_node"
            ],
            "edge_types": [
                [
                    "context",
                    "element",
                    "property",
                    "internal",
                    "hidden",
                    "shortcut",
                    "weak"
                ],
                "string_or_number",
                "node"
            ]
        }
    }
}

Nodes

La nodes matriz, que se encuentra en el nivel superior de los .heapsnapshot datos, contiene toda la información necesaria para volver a crear los nodos del gráfico de memoria.

Para analizar esta matriz, se necesita la siguiente información:

  • snapshot.node_count, para saber cuántos nodos hay.
  • snapshot.meta.node_fields, para saber cuántos campos tiene cada nodo.

Cada nodo de la matriz se representa mediante una serie de snapshot.meta.node_fields.length números. Por lo tanto, el número total de elementos de la nodes matriz se snapshot.node_count multiplica por snapshot.meta.node_fields.length.

Para volver a crear un nodo, lea los números de la nodes matriz por grupos de tamaño snapshot.meta.node_fields.length.

El siguiente fragmento de código muestra los node_fields metadatos y los datos de los dos primeros nodos del gráfico:

{
    "snapshot": {
        "meta": {
            "node_fields": [
                "type",
                "name",
                "id",
                "self_size",
                "edge_count",
                "trace_node_id",
                "detachedness"
            ]
            ...
        }
        ...
    },
    "nodes": [
        9,1,1,0,10,0,0,
        2,1,79,12,1,0,0,
        ...
    ]
    ...
}
Índice en el grupo de nodos Nombre Descripción
0 type Tipo de nodo. Consulte Tipos de nodo, a continuación.
1 name Nombre del nodo. Este es un número que es el índice de la matriz de nivel strings superior. Para buscar el nombre real, use el número de índice para buscar la cadena en la matriz de nivel strings superior.
2 id Identificador único del nodo.
3 self_size Tamaño del nodo en bytes.
4 edge_count Número de bordes conectados a este nodo.
5 trace_node_id Identificador del nodo de seguimiento
6 detachedness Si se puede acceder a este nodo desde el window objeto global. 0 significa que el nodo no está desasociado; Se puede acceder al nodo desde el window objeto global. 1 significa que el nodo está desasociado; No se puede acceder al nodo desde el window objeto global.

Tipos de nodo

El primer número del grupo de números de un nodo de la nodes matriz corresponde a su tipo. Este número es un índice que se puede usar para buscar el nombre de tipo en la snapshot.meta.node_types[0] matriz.

Tipo de nodo Descripción
Hidden Elemento interno V8 que no se corresponde directamente con un objeto JavaScript controlable por el usuario. En DevTools, todos se muestran bajo el nombre de categoría (sistema). Aunque estos objetos son internos, pueden ser una parte importante de las rutas de acceso de retención.
Objeto Cualquier objeto definido por el usuario, como { x: 2 } o new Foo(4). Los contextos, que se muestran en DevTools como system/Context, contienen variables que tenían que asignarse en el montón porque las usa una función anidada.
Nativa Elementos asignados por el motor de representación de Blink, en lugar de por V8. Estos son principalmente elementos DOM, como HTMLDivElement o CSSStyleRule.
Cadena concatenada Resultado de concatenar dos cadenas con el + operador . En lugar de crear una nueva cadena que contenga una copia de todos los datos de las dos cadenas de origen, V8 crea un ConsString objeto que contiene punteros a las dos cadenas de origen. Desde una perspectiva de JavaScript, actúa igual que cualquier otra cadena, pero desde una perspectiva de generación de perfiles de memoria, es diferente.
Cadena segmentada Resultado de una operación de subcadena, como usar String.prototype.substr o String.prototype.substring. V8 evita copiar datos de cadena mediante la creación de , SlicedStringque apunta a la cadena original y especifica el índice de inicio y la longitud. Desde una perspectiva de JavaScript, una cadena segmentada actúa como cualquier otra cadena, pero desde una perspectiva de generación de perfiles de memoria, es diferente.
Matriz Varias listas internas, que se muestran en DevTools con el nombre de categoría (matriz). Al igual que Hidden, esta categoría agrupa una variedad de cosas. Muchos de los objetos aquí se denominan (propiedades de objeto) o (elementos de objeto), lo que indica que contienen las propiedades con clave de cadena o con clave numérica de un objeto JavaScript.
Código Elementos que aumentan proporcionalmente a la cantidad de script o al número de veces que se ejecutan las funciones.
Sintético Los nodos sintéticos no se corresponden con nada realmente asignado en la memoria. Se usan para distinguir los distintos tipos de raíces de recolección de elementos no utilizados (GC).

Bordes

De forma similar a la nodes matriz, la edges matriz de nivel superior contiene todos los elementos necesarios para volver a crear los bordes del gráfico de memoria.

También de forma similar a los nodos, el número total de bordes se puede calcular multiplicando snapshot.edge_count por snapshot.meta.edge_fields.length. Los bordes también se almacenan como una secuencia de números, en los que deberá recorrer en iteración por grupos de tamaño snapshot.meta.edge_fields.length.

Sin embargo, para leer la edges matriz correctamente, primero debe leer la nodes matriz, ya que cada nodo sabe cuántos bordes tiene.

Para volver a crear un borde, necesita tres elementos de información:

  • Tipo de borde.
  • Nombre o índice perimetral.
  • Nodo al que está conectado el perímetro.

Por ejemplo, si lee el primer nodo de la nodes matriz y su edge_count propiedad se establece en 4, los cuatro primeros grupos de números de snapshot.meta.edge_fields.length la edges matriz se corresponden con los cuatro bordes de este nodo.

Índice en grupo perimetral Nombre Descripción
0 type Tipo de borde. Consulte Tipos de Edge para averiguar cuáles son los tipos posibles.
1 name_or_index Puede ser un número o una cadena. Si es un número, corresponde al índice de la matriz de nivel strings superior, donde se puede encontrar el nombre del borde.
2 to_node Índice dentro de la matriz a la nodes que está conectado este borde.

Tipos perimetrales

El primer número del grupo de números de un borde de la edges matriz corresponde a su tipo. Este número es un índice que se puede usar para buscar el nombre de tipo en la snapshot.meta.edge_types[0] matriz.

Tipo perimetral Descripción
Interno Los bordes que no se corresponden con nombres visibles de JavaScript, pero siguen siendo importantes. Por ejemplo, las instancias de Function tienen un "contexto" que representa el estado de las variables que estaban en el ámbito donde se definió la función. No hay ninguna manera de que el código JavaScript lea directamente el "contexto" de una función, pero estos bordes son necesarios al investigar los retenes.
Débil Los bordes débiles no mantienen activo el nodo al que están conectados y, por tanto, se omiten de la vista Retenedores. La recolección de elementos no utilizados (GC) puede descartar cualquier objeto con solo bordes débiles que apunten a él.
Hidden De forma similar a Interno, excepto que estos bordes no tienen nombres únicos y, en su lugar, se numeran en orden creciente.
Acceso directo Representación más fácil de leer de otra ruta de acceso. Este tipo se usa rara vez. Por ejemplo, si usa Function.prototype.bind para crear una función enlazada con algunos argumentos enlazados, V8 crea un JSBoundFunction, que apunta a ( FixedArray un tipo interno), que apunta a cada argumento enlazado. Al generar una instantánea, V8 agrega un borde de acceso directo de la función enlazada directamente a cada argumento enlazado, omitiendo .FixedArray
Elemento Propiedades del objeto donde la clave es un número.

locations

La locations matriz, que se encuentra en el nivel superior de los .heapsnapshot datos, contiene información sobre dónde se crearon algunos de los nodos de la instantánea. Esta matriz consta de una serie de números destinados a ser leídos por grupos de tamaño snapshot.meta.location_fields.length. Por lo tanto, vamos a snapshot.meta.location_fields saber cuántos campos tiene cada ubicación de la locations matriz y cuáles son esos campos. Por ejemplo, si location_fields contiene 4 elementos, los grupos de 4 deben leer la locations matriz.

snapshot.meta.location_fields contiene la información de cada ubicación:

Índice en location_fields Nombre Descripción
0 object_index Índice del nodo de la snapshot.nodes matriz asociada a esta ubicación.
1 script_id Identificador del script que crea el nodo asociado.
2 line Número de línea donde se creó el nodo, dentro del script que creó el nodo.
3 column Número de columna donde se creó el nodo, dentro del script que creó el nodo.

En el ejemplo de código siguiente se muestra cómo vincular la snapshot.locations matriz a la snapshot.nodes matriz:

{
    "snapshot": {
        "meta": {
            "location_fields": [
                "object_index",
                "script_id",
                "line",
                "column"
            ]
            ...
        }
        ...
    },
    "nodes": [
        9,1,1,0,10,0,0,
        2,1,79,12,1,0,0,
        ...
    ],
    "locations":[
        7,9,0,0,
        113792,3,25,21,
        ...
    ],
    ...
}

La primera ubicación de la locations matriz es 7,9,0,0,. Esta ubicación está asociada al grupo de información de nodo que comienza en el índice 7 de la nodes matriz. Por lo tanto, el nodo contiene los siguientes pares clave-valor:

"type": 2,
"name": 1,
"id": 79,
"self_size": 12,
"edge_count": 1,
"trace_node_id": 0,
"detachedness": 0,
"script_id": 9,
"line" 0,
"column": 0,

Vea también

Para obtener más información sobre el formato de .heapsnapshot archivo, vea el código que genera el archivo, que es la HeapSnapshotGenerator clase en heap-snapshot-generator.h.