A área dinâmica para dados snapshot formato de ficheiro
Investigar a utilização da memória em aplicações Web pode ser difícil. A ferramenta DevTools Memory permite-lhe explorar todos os objetos que são alocados na memória, através da sua aplicação Web, através de uma área dinâmica para dados snapshot. Estas informações são úteis para investigações de desempenho porque pode descobrir que objetos estão a consumir mais memória.
No entanto, por vezes poderá ter de se concentrar em partes específicas dos dados de memória que a ferramenta Memória não mostra. Neste caso, utilize DevTools para exportar todo o conjunto de dados de memória como um .heapsnapshot
ficheiro JSON.
Este artigo descreve a estrutura e o conteúdo dos .heapsnapshot
ficheiros JSON para que possa criar as suas próprias ferramentas de visualização e análise.
Registar uma área dinâmica para dados snapshot
Para exportar um .heapsnapshot
ficheiro, primeiro tem de registar uma área dinâmica para dados snapshot na ferramenta Memória, da seguinte forma:
No Microsoft Edge, navegue para o site a partir do qual pretende exportar os dados.
Prima Ctrl+Shift+I (Windows, Linux) ou Comando+Opção+I (macOS) para abrir as Devtools.
Abra a ferramenta Memória .
Selecione Área dinâmica para dados snapshot e, em seguida, clique em Tomar snapshot.
Para obter mais informações, veja Record heap snapshots using the Memory tool ("Heap snapshot" profiling type).
Exportar e ver um .heapsnapshot
ficheiro
Depois de registar uma área dinâmica para dados snapshot, pode exportá-la.
Na barra lateral esquerda da ferramenta Memória, clique em Guardar junto à área dinâmica para dados snapshot item que acabou de gravar.
Altere a extensão de ficheiro de
.heapsnapshot
para.json
, para facilitar a abertura do ficheiro num editor de texto.Abra o ficheiro guardado num editor de texto, como Visual Studio Code.
Para facilitar a leitura do JSON, no Visual Studio Code, clique com o botão direito do rato em qualquer parte do código e, em seguida, selecione Formatar documento.
Geralmente, o ficheiro resultante .heapsnapshot
é diferente sempre que grava e exporta uma área dinâmica para dados snapshot. Os instantâneos de área dinâmica são gerados de forma dinâmica, com base no conteúdo da aplicação Web que está atualmente a ser inspecionada nas DevTools.
Descrição geral do formato de .heapsnapshot
ficheiro
A memória utilizada por uma aplicação Web é organizada como um gráfico por V8, que é o motor JavaScript utilizado pelo Microsoft Edge. Um gráfico é um tipo de dados composto por nós (pontos no gráfico) e arestas (ligações entre os pontos).
Os dados no .heapsnapshot
ficheiro representam a memória da aplicação Web que grafa de forma eficiente e facilitam a transferência de grupos de dados entre o processo do browser e as DevTools. O .heapsnapshot
ficheiro contém uma representação simplificada das relações entre nós e arestas, como um objeto JSON que contém matrizes de números e cadeias. O ficheiro tem uma .heapsnapshot
extensão de nome de ficheiro e contém dados formatados em JSON.
Os dados têm duas partes main:
- Os metadados, que contêm todas as informações necessárias para analisar as matrizes de dados que representam o gráfico de memória.
- Os dados das matrizes, que contêm os dados reais necessários para recriar o gráfico.
Atualizar esta documentação de formato de dados
O formato do .heapsnapshot
ficheiro, conforme documentado abaixo, pode mudar à medida que v8 e DevTools evoluem. Se encontrar uma discrepância na documentação, forneça feedback no repositório MicrosoftDocs/edge-developer.
Esquema dos .heapsnapshot
dados
Estrutura de nível superior
Os .heapsnapshot
dados JSON contêm um objeto de raiz que tem as seguintes propriedades:
{
"snapshot": {},
"nodes": [],
"edges": [],
"trace_function_infos": [],
"trace_tree": [],
"samples": [],
"locations": [],
"strings": []
}
Propriedade | Descrição | Formatar |
---|---|---|
snapshot |
Contém todas as informações sobre o formato dos dados do gráfico de memória e o respetivo tamanho. | Object |
nodes |
Todas as informações necessárias para recriar os nós do gráfico. Para analisar estes dados, utilize snapshot.meta.node_types e snapshot.meta.node_fields . |
Array |
edges |
Todas as informações necessárias para recriar as margens do gráfico. Para analisar estes dados, utilize snapshot.meta.edge_types e snapshot.meta.edge_fields . |
Array |
trace_function_infos |
Ainda não documentado | Array |
trace_tree |
Ainda não documentado | Array |
samples |
Ainda não documentado | Array |
locations |
Contém informações sobre a localização do script dos nós. Para analisar estes dados, utilize snapshot.meta.location_fields com a nodes matriz . |
Array |
strings |
Uma matriz de todas as cadeias que são mantidas na memória. Estas podem ser cadeias de carateres, como cadeias definidas pelo utilizador ou código. | Array |
Instantâneo
{
"snapshot": {
"meta": {},
"node_count": 123,
"edge_count": 456,
"trace_function_count": 0
}
...
}
Propriedade | Descrição | Formatar |
---|---|---|
meta |
Propriedades que contêm informações sobre a forma e o tamanho de cada objeto contido nos dados do gráfico de memória. | Object |
node_count |
O número total de nós no gráfico de memória. | Number |
edge_count |
O número total de arestas no gráfico de memória. | Number |
trace_function_count |
O número total de funções de rastreio no gráfico de memória. | Number |
Metadados de instantâneo
{
"snapshot": {
"meta": {
"node_fields": [],
"node_types": [],
"edge_fields": [],
"edge_types": []
}
}
...
}
Propriedade | Descrição | Formatar |
---|---|---|
node_fields |
A lista de todas as propriedades necessárias para recriar um nó. | Array |
node_types |
Os tipos de todas as propriedades necessárias para recriar um nó. O número de tipos é o mesmo que o número de propriedades definidas em node_fields . |
Array |
edge_fields |
A lista de todas as propriedades necessárias para recriar um edge. | Array |
edge_types |
Os tipos de todas as propriedades necessárias para recriar uma aresta. O número de tipos é o mesmo número de propriedades em edge_fields . |
Array |
Segue-se um exemplo de um objeto de metadados:
{
"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"
]
}
}
}
Nós
A nodes
matriz, que está no nível superior dos .heapsnapshot
dados, contém todas as informações necessárias para recriar os nós do gráfico de memória.
Para analisar esta matriz, são necessárias as seguintes informações:
-
snapshot.node_count
, para saber quantos nós existem. -
snapshot.meta.node_fields
, para saber quantos campos cada nó tem.
Cada nó na matriz é representado por uma série de snapshot.meta.node_fields.length
números. Assim, o número total de elementos na nodes
matriz é snapshot.node_count
multiplicado por snapshot.meta.node_fields.length
.
Para recriar um nó, leia os números da nodes
matriz por grupos de tamanho snapshot.meta.node_fields.length
.
O fragmento de código seguinte mostra os node_fields
metadados e os dados dos dois primeiros nós no 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 no grupo de nós | Nome | Descrição |
---|---|---|
0 |
type |
O tipo de nó. Veja Tipos de nós abaixo. |
1 |
name |
O nome do nó. Este é um número que é o índice na matriz de nível strings superior. Para localizar o nome real, utilize o número do índice para procurar a cadeia na matriz de nível strings superior. |
2 |
id |
O ID exclusivo do nó. |
3 |
self_size |
O tamanho do nó em bytes. |
4 |
edge_count |
O número de arestas ligadas a este nó. |
5 |
trace_node_id |
O ID do nó de rastreio |
6 |
detachedness |
Se este nó pode ser alcançado a window partir do objeto global.
0 significa que o nó não está desanexado; o nó pode ser alcançado a window partir do objeto global.
1 significa que o nó está desanexado; não é possível aceder ao nó a window partir do objeto global. |
Tipos de nós
O primeiro número no grupo de números de um nó na nodes
matriz corresponde ao respetivo tipo. Este número é um índice que pode ser utilizado para procurar o nome do snapshot.meta.node_types[0]
tipo na matriz.
Tipo de nó | Descrição |
---|---|
Hidden | Um elemento interno V8 que não corresponde diretamente a um objeto JavaScript controlável pelo utilizador. Nas DevTools, todas estas são apresentadas sob o nome da categoria (sistema). Embora estes objetos sejam internos, podem ser uma parte importante dos caminhos de retenção. |
Objeto | Qualquer objeto definido pelo utilizador, como { x: 2 } ou new Foo(4) . Os contextos, que aparecem em DevTools como sistema/Contexto, contêm variáveis que tiveram de ser alocadas na área dinâmica para dados porque são utilizadas por uma função aninhada. |
Nativo | Itens que são alocados pelo motor de composição Blink, em vez de por V8. Trata-se principalmente de itens DOM, como HTMLDivElement ou CSSStyleRule . |
Cadeia concatenada | O resultado da concatenação de duas cadeias com o + operador . Em vez de criar uma nova cadeia que contém uma cópia de todos os dados das duas cadeias de origem, o V8 cria um ConsString objeto que contém ponteiros para as duas cadeias de origem. Do ponto de vista do JavaScript, funciona como qualquer outra cadeia, mas, do ponto de vista da criação de perfis de memória, é diferente. |
Cadeia segmentada | O resultado de uma operação de subcadeia, como utilizar String.prototype.substr ou String.prototype.substring . O V8 evita copiar dados de cadeia ao criar, em vez disso, um SlicedString , que aponta para a cadeia original e especifica o índice de início e o comprimento. Do ponto de vista do JavaScript, uma cadeia segmentada age como qualquer outra cadeia, mas, do ponto de vista da criação de perfis de memória, é diferente. |
Matriz | Várias listas internas, que são apresentadas em DevTools com o nome da categoria (matriz). Tal como Oculto, esta categoria agrupa uma variedade de itens. Muitos dos objetos aqui indicados têm o nome (propriedades do objeto) ou (elementos de objeto), o que indica que contêm as propriedades com chave de cadeia ou chave numérica de um objeto JavaScript. |
Código | Coisas que crescem proporcionalmente à quantidade de script e/ou ao número de vezes que as funções são executadas. |
Sintético | Os nós sintéticos não correspondem a nada realmente atribuído na memória. Estes são utilizados para distinguir os diferentes tipos de raízes de libertação da memória (GC). |
Arestas
Semelhante à nodes
matriz, a edges
matriz de nível superior contém todos os elementos necessários para recriar as margens do gráfico de memória.
Também semelhante aos nós, o número total de arestas pode ser calculado multiplicando snapshot.edge_count
por snapshot.meta.edge_fields.length
. As arestas também são armazenadas como uma sequência de números, que terá de iterar por grupos de tamanho snapshot.meta.edge_fields.length
.
No entanto, para ler a edges
matriz corretamente, primeiro tem de ler a nodes
matriz, uma vez que cada nó sabe quantas arestas tem.
Para recriar uma aresta, precisa de três informações:
- O tipo de limite.
- O nome ou índice do edge.
- O nó ao qual a extremidade está ligada.
Por exemplo, se ler o primeiro nó na matriz e a nodes
respetiva edge_count
propriedade estiver definida como 4, os primeiros quatro grupos de snapshot.meta.edge_fields.length
números na edges
matriz correspondem às quatro margens deste nó.
Índice no grupo edge | Nome | Descrição |
---|---|---|
0 |
type |
O tipo de aresta. Veja Tipos de edge para saber quais são os tipos possíveis. |
1 |
name_or_index |
Pode ser um número ou uma cadeia. Se for um número, corresponde ao índice na matriz de nível strings superior, onde o nome da margem pode ser encontrado. |
2 |
to_node |
O índice dentro da nodes matriz à qual esta aresta está ligada. |
Tipos de arestas
O primeiro número no grupo de números de uma margem na edges
matriz corresponde ao respetivo tipo. Este número é um índice que pode ser utilizado para procurar o nome do snapshot.meta.edge_types[0]
tipo na matriz.
Tipo de limite | Descrição |
---|---|
Interno | As arestas que não correspondem a nomes visíveis para JavaScript, mas que ainda são importantes. Por exemplo, as Instâncias de função têm um "contexto" que representa o estado das variáveis que estavam no âmbito onde a função foi definida. Não há forma de o código JavaScript ler diretamente o "contexto" de uma função, mas estas arestas são necessárias para investigar os retentores. |
Fraco | As arestas fracas não mantêm o nó ao qual estão ligados vivos e, portanto, são omitidos da vista Retentores. Qualquer objeto com apenas arestas fracas a apontar para o mesmo pode ser eliminado pela libertação da memória (GC). |
Hidden | Semelhante a Interno, exceto que estas arestas não têm nomes exclusivos e, em vez disso, são numeradas por ordem crescente. |
Shortcut | Uma representação mais fácil de ler de outro caminho. Este tipo raramente é utilizado. Por exemplo, se utilizar Function.prototype.bind para criar uma função vinculada com alguns argumentos vinculados, v8 cria um JSBoundFunction , que aponta para um (um FixedArray tipo interno), que aponta para cada argumento vinculado. Ao produzir um snapshot, o V8 adiciona um limite de atalho da função vinculada diretamente a cada argumento vinculado, ignorando o FixedArray . |
Elemento | Propriedades do objeto em que a chave é um número. |
locations
A locations
matriz, que está no nível superior dos .heapsnapshot
dados, contém informações sobre onde alguns dos nós na snapshot foram criados. Esta matriz consiste numa série de números destinados a serem lidos por grupos de tamanho snapshot.meta.location_fields.length
. Por conseguinte, iremos snapshot.meta.location_fields
saber quantos campos cada localização na locations
matriz tem e quais são esses campos. Por exemplo, se location_fields
contiver 4 itens, a locations
matriz deve ser lida por grupos de 4.
snapshot.meta.location_fields
contém as informações para cada localização:
Indexar em location_fields |
Nome | Descrição |
---|---|---|
0 |
object_index |
O índice do nó na snapshot.nodes matriz associada a esta localização. |
1 |
script_id |
O ID do script que cria o nó associado. |
2 |
line |
O número de linha onde o nó foi criado, dentro do script que criou o nó. |
3 |
column |
O número da coluna onde o nó foi criado, dentro do script que criou o nó. |
O exemplo de código seguinte mostra como ligar a snapshot.locations
matriz à 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,
...
],
...
}
A primeira localização na locations
matriz é 7,9,0,0,
. Esta localização está associada ao grupo de informações do nó que começa no índice 7 na nodes
matriz. Por conseguinte, o nó contém os seguintes pares chave/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,
Confira também
Para saber mais sobre o formato de .heapsnapshot
ficheiro, veja o código que gera o ficheiro, que é a HeapSnapshotGenerator
classe em heap-snapshot-generator.h
.