Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Investigar o uso de memória em aplicativos Web pode ser difícil. A ferramenta Memória do DevTools permite explorar todos os objetos alocados na memória pelo seu aplicativo Web usando um heap snapshot. Essas informações são úteis para investigações de desempenho porque você pode descobrir quais objetos estão consumindo mais memória.
No entanto, às vezes você pode precisar se concentrar em partes específicas dos dados de memória que a ferramenta Memória não mostra. Nesse caso, use o DevTools para exportar todo o conjunto de dados de memória como um .heapsnapshot arquivo JSON.
Este artigo descreve a estrutura e o conteúdo dos arquivos JSON para que você possa criar suas próprias ferramentas de .heapsnapshot visualização e análise.
Registrar um snapshot de heap
Para exportar um .heapsnapshot arquivo, primeiro você precisa registrar um snapshot de heap na ferramenta Memória, da seguinte forma:
No Microsoft Edge, navegue até o site do qual você deseja exportar os dados.
Pressione Ctrl+Shift+I (Windows, Linux) ou Command+Option+I (macOS) para abrir o Devtools.
Abra a ferramenta Memória .
Selecione Heap snapshot e clique em Take snapshot.
Para obter mais informações, consulte Registrar instantâneos de heap usando a ferramenta Memória (tipo de criação de perfil "Heap snapshot")
Exportar e exibir um .heapsnapshot arquivo
Depois de gravar um snapshot de heap, você pode exportá-lo.
Na barra lateral esquerda da ferramenta Memória, clique em Salvar ao lado do item do snapshot de heap que você acabou de gravar.
Altere a extensão de arquivo de para
.json, para facilitar a abertura do arquivo em um editor de.heapsnapshottexto.Abra o arquivo salvo em um editor de texto, como o Visual Studio Code.
Para facilitar a leitura do JSON, no Visual Studio Code, clique com o botão direito do mouse em qualquer lugar do código e selecione Formatar documento.
Geralmente, o arquivo resultante .heapsnapshot é diferente toda vez que você grava e exporta um snapshot de heap. Os instantâneos de heap são gerados dinamicamente, com base no conteúdo do aplicativo Web que está sendo inspecionado no momento no DevTools.
Visão geral do .heapsnapshot formato de arquivo
A memória usada por um aplicativo Web é organizada como um gráfico pelo V8, que é o mecanismo JavaScript usado pelo Microsoft Edge. Um gráfico é um tipo de dados composto por nós (pontos no gráfico) e bordas (vínculos entre os pontos).
Os dados no .heapsnapshot arquivo representam a memória do aplicativo Web que representa graficamente com eficiência e facilita a transferência de grupos de dados entre o processo do navegador e o DevTools. O .heapsnapshot arquivo contém uma representação achatada das relações entre nós e bordas, como um objeto JSON que contém matrizes de números e strings. O arquivo tem uma .heapsnapshot extensão de nome de arquivo e contém dados formatados em JSON.
Os dados têm duas partes principais:
- 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 de matrizes, que contêm os dados reais necessários para recriar o gráfico.
Atualizando esta documentação de formato de dados
O formato do arquivo, conforme documentado abaixo, pode mudar à medida que o V8 e o .heapsnapshot DevTools evoluem. Se você encontrar uma discrepância na documentação, forneça comentários no repositório MicrosoftDocs/edge-developer.
Esquema dos .heapsnapshot dados
Estrutura de nível superior
Os .heapsnapshot dados JSON contêm um objeto 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 seu tamanho. | Object |
nodes |
Todas as informações necessárias para recriar os nós do gráfico. Para analisar esses dados, use snapshot.meta.node_types e snapshot.meta.node_fields. |
Array |
edges |
Todas as informações necessárias para recriar as bordas do gráfico. Para analisar esses dados, use 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 de nós. Para analisar esses dados, use snapshot.meta.location_fields com a nodes matriz. |
Array |
strings |
Uma matriz de todas as cadeias de caracteres que são mantidas na memória. Podem ser quaisquer cadeias de caracteres, como cadeias de caracteres definidas pelo usuário 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 rastreamento 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 é igual ao número de propriedades definidas em node_fields. |
Array |
edge_fields |
A lista de todas as propriedades necessárias para recriar uma aresta. | Array |
edge_types |
Os tipos de todas as propriedades necessárias para recriar uma aresta. O número de tipos é o mesmo, o número de propriedades em edge_fields. |
Array |
Veja a seguir 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 essa matriz, as seguintes informações são necessárias:
-
snapshot.node_count, para saber quantos nós existem. -
snapshot.meta.node_fields, para saber quantos campos cada nó tem.
Cada nó da matriz é representado por uma série de snapshot.meta.node_fields.length números. Portanto, 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 trecho de código a seguir 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ó. Consulte Tipos de nó, abaixo. |
1 |
name |
O nome do nó. Esse é um número que é o índice na matriz de nível strings superior. Para localizar o nome real, use o número de índice para pesquisar a cadeia de caracteres na matriz de nível strings superior. |
2 |
id |
A ID exclusiva do nó. |
3 |
self_size |
O tamanho do nó em bytes. |
4 |
edge_count |
O número de arestas conectadas a este nó. |
5 |
trace_node_id |
A ID do nó de rastreamento |
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 acessado a window partir do objeto global.
1 significa que o nó está desanexado; O nó não pode ser alcançado a window partir do objeto global. |
Tipos de nó
O primeiro número no grupo de números de um nó na nodes matriz corresponde ao seu tipo. Esse número é um índice que pode ser usado para pesquisar o nome do tipo na snapshot.meta.node_types[0] matriz.
| Tipo de nó | Descrição |
|---|---|
| Hidden | Um elemento interno do V8 que não corresponde diretamente a um objeto JavaScript controlável pelo usuário. No DevTools, todos eles aparecem no nome da categoria (sistema). Embora esses objetos sejam internos, eles podem ser uma parte importante dos caminhos de retenção. |
| Objeto | Qualquer objeto definido pelo usuário, como { x: 2 } ou new Foo(4). Os contextos, que aparecem no DevTools como sistema / Contexto, contêm variáveis que tiveram que ser alocadas no heap porque são usadas por uma função aninhada. |
| Nativo | Coisas que são alocadas pelo mecanismo de renderização Blink, em vez de pelo V8. Na maioria deles, são itens DOM, como HTMLDivElement ou CSSStyleRule. |
| Cadeia de caracteres concatenada | O resultado da concatenação de duas cadeias de caracteres com o + operador. Em vez de criar uma nova string que contenha uma cópia de todos os dados das duas strings de origem, o V8 cria um ConsString objeto que contém ponteiros para as duas strings de origem. Do ponto de vista do JavaScript, ele age como qualquer outra cadeia de caracteres, mas do ponto de vista da criação de perfil de memória, é diferente. |
| Cadeia de caracteres fatiada | O resultado de uma operação de substring, como using String.prototype.substr ou String.prototype.substring. O V8 evita copiar dados de cadeia de caracteres criando, em vez disso, um SlicedString, que aponta para a cadeia de caracteres original e especifica o índice inicial e o comprimento. De uma perspectiva do JavaScript, uma cadeia de caracteres fatiada age como qualquer outra cadeia de caracteres, mas de uma perspectiva de criação de perfil de memória, é diferente. |
| Matriz | Várias listas internas, que são exibidas no DevTools com o nome da categoria (matriz). Como Oculto, esta categoria agrupa uma variedade de coisas. Muitos dos objetos aqui são nomeados (propriedades do objeto) ou (elementos do objeto), indicando que eles contêm as propriedades com chave de cadeia de caracteres 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 alocado na memória. Eles são usados para distinguir os diferentes tipos de raízes de coleta de lixo (GC). |
Arestas
Semelhante à nodes matriz, a edges matriz de nível superior contém todos os elementos necessários para recriar as bordas 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 você precisará iterar por grupos de tamanho snapshot.meta.edge_fields.length.
No entanto, para ler a edges matriz corretamente, primeiro você precisa ler a nodes matriz, porque cada nó sabe quantas arestas ele tem.
Para recriar uma borda, você precisa de três informações:
- O tipo de borda.
- O nome ou índice da borda.
- O nó ao qual a borda está conectada.
Por exemplo, se você ler o primeiro nó da nodes matriz e sua edge_count propriedade estiver definida como 4, os primeiros quatro grupos de snapshot.meta.edge_fields.length números na matriz corresponderão edges às quatro arestas desse nó.
| Índice no grupo de borda | Nome | Descrição |
|---|---|---|
0 |
type |
O tipo de borda. Consulte Tipos de borda para descobrir quais são os tipos possíveis. |
1 |
name_or_index |
Pode ser um número ou uma cadeia de caracteres. Se for um número, ele corresponde ao índice na matriz de nível strings superior, onde o nome da borda pode ser encontrado. |
2 |
to_node |
O índice dentro da nodes matriz ao qual essa borda está conectada. |
Tipos de borda
O primeiro número no grupo de números de uma aresta na edges matriz corresponde ao seu tipo. Esse número é um índice que pode ser usado para pesquisar o nome do tipo na snapshot.meta.edge_types[0] matriz.
| Tipo de borda | Descrição |
|---|---|
| Interno | Bordas que não correspondem a nomes visíveis em JavaScript, mas 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 escopo em que a função foi definida. Não há como o código JavaScript ler diretamente o "contexto" de uma função, mas essas bordas são necessárias ao investigar os retentores. |
| Fraco | As arestas fracas não mantêm ativo o nó ao qual estão conectadas e, portanto, são omitidas da exibição de Retentores. Qualquer objeto com apenas bordas fracas apontando para ele pode ser descartado pela GC (coleta de lixo). |
| Hidden | Semelhante a Interno, exceto que essas bordas não têm nomes exclusivos e, em vez disso, são numeradas em ordem crescente. |
| Shortcut | Uma representação mais fácil de ler de algum outro caminho. Esse tipo é raramente usado. Por exemplo, se você usa Function.prototype.bind para criar uma função associada com alguns argumentos associados, o V8 cria um JSBoundFunction, que aponta para a FixedArray (um tipo interno), que aponta para cada argumento associado. Ao produzir um snapshot, o V8 adiciona uma borda de atalho da função vinculada diretamente a cada argumento associado, 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 no snapshot foram criados. Essa matriz consiste em uma série de números destinados a serem lidos por grupos de tamanho snapshot.meta.location_fields.length. Portanto, iríamos para snapshot.meta.location_fields saber quantos campos cada local da locations matriz tem e quais são esses campos. Por exemplo, se location_fields contiver 4 itens, a locations matriz deverá ser lida por grupos de 4.
snapshot.meta.location_fields Contém as informações para cada local:
Índice de entrada location_fields |
Nome | Descrição |
|---|---|---|
0 |
object_index |
O índice do nó na snapshot.nodes matriz associada a esse local. |
1 |
script_id |
A ID do script que cria o nó associado. |
2 |
line |
O número de linha em que o nó foi criado, dentro do script que criou o nó. |
3 |
column |
O número da coluna em que o nó foi criado, dentro do script que criou o nó. |
O exemplo de código a seguir mostra como vincular 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,
...
],
...
}
O primeiro local na locations matriz é 7,9,0,0,. Esse local está associado ao grupo de informações do nó que começa no índice 7 na nodes matriz. Portanto, o nó contém os seguintes pares de 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 arquivo, consulte o código que gera o arquivo, que é a HeapSnapshotGenerator classe em heap-snapshot-generator.h.