Freigeben über


Das Heap-Momentaufnahme-Dateiformat

Die Untersuchung der Speicherauslastung in Webanwendungen kann schwierig sein. Mit dem DevTools-Speichertool können Sie alle Objekte untersuchen, die von Ihrer Webanwendung im Arbeitsspeicher zugeordnet werden, indem Sie einen Heap Momentaufnahme. Diese Informationen sind für Leistungsuntersuchungen nützlich, da Sie herausfinden können, welche Objekte den meisten Arbeitsspeicher verbrauchen.

Manchmal müssen Sie sich jedoch auf bestimmte Teile der Speicherdaten konzentrieren, die vom Speichertool nicht angezeigt werden. Verwenden Sie in diesem Fall DevTools, um den gesamten Satz von Speicherdaten als .heapsnapshot JSON-Datei zu exportieren.

In diesem Artikel werden die Struktur und der Inhalt von .heapsnapshot JSON-Dateien beschrieben, damit Sie Ihre eigenen Visualisierungs- und Analysetools erstellen können.

Aufzeichnen eines Heaps Momentaufnahme

Um eine .heapsnapshot Datei zu exportieren, müssen Sie zunächst wie folgt einen Heap-Momentaufnahme im Speichertool aufzeichnen:

  1. Navigieren Sie in Microsoft Edge zu der Website, von der Sie die Daten exportieren möchten.

  2. Drücken Sie STRG+UMSCHALT+I (Windows, Linux) oder BEFEHL+WAHL+I (macOS), um DevTools zu öffnen.

  3. Öffnen Sie das Speichertool .

  4. Wählen Sie Heap Momentaufnahme aus, und klicken Sie dann auf Momentaufnahme.

Weitere Informationen finden Sie unter Aufzeichnen von Heapmomentaufnahmen mit dem Speichertool ("Profilerstellungstyp Heap Momentaufnahme").

Exportieren und Anzeigen einer .heapsnapshot Datei

Nachdem Sie einen Heap Momentaufnahme aufgezeichnet haben, können Sie ihn exportieren.

  1. Klicken Sie in der linken Seitenleiste des Speichertools neben dem Heap Momentaufnahme soeben aufgezeichneten Elements auf Speichern.

  2. Ändern Sie die Dateierweiterung von in .heapsnapshot.json, um das Öffnen der Datei in einem Text-Editor zu vereinfachen.

  3. Öffnen Sie die gespeicherte Datei in einem Text-Editor, z. B. Visual Studio Code.

  4. Um die Lesbarkeit des JSON-Codes zu vereinfachen, klicken Sie in Visual Studio Code mit der rechten Maustaste auf eine beliebige Stelle im Code, und wählen Sie dann Dokument formatieren aus.

Im Allgemeinen unterscheidet sich die resultierende .heapsnapshot Datei jedes Mal, wenn Sie einen Heap Momentaufnahme aufzeichnen und exportieren. Heapmomentaufnahmen werden basierend auf dem Inhalt der Webanwendung, die derzeit in DevTools untersucht wird, dynamisch generiert.

Übersicht über das .heapsnapshot Dateiformat

Der von einer Webanwendung verwendete Arbeitsspeicher wird von V8 als Graph organisiert. Dies ist die javaScript-Engine, die von Microsoft Edge verwendet wird. Ein Graph ist ein Datentyp, der aus Knoten (Punkten im Diagramm) und Kanten (Verknüpfungen zwischen den Punkten) besteht.

Die Daten in der .heapsnapshot Datei stellen den Arbeitsspeicher der Web-App dar, der effizient graphisch dargestellt wird, und erleichtern die Übertragung von Datengruppen zwischen dem Browserprozess und DevTools. Die .heapsnapshot Datei enthält eine vereinfachte Darstellung der Beziehungen zwischen Knoten und Kanten als JSON-Objekt, das Arrays von Zahlen und Zeichenfolgen enthält. Die Datei verfügt über eine .heapsnapshot Dateinamenerweiterung und enthält Daten im JSON-Format.

Die Daten bestehen aus zwei Standard Teilen:

  • Die Metadaten, die alle Informationen enthalten, die Sie benötigen, um die Arrays von Daten zu analysieren, die das Speicherdiagramm darstellen.
  • Die Arraydaten, die die tatsächlichen Daten enthalten, die zum erneuten Erstellen des Graphen erforderlich sind.

Aktualisieren der Dokumentation zu diesem Datenformat

Das Format der .heapsnapshot Datei, wie unten dokumentiert, kann sich mit der Weiterentwicklung von V8 und DevTools ändern. Wenn Sie eine Diskrepanz in der Dokumentation feststellen, senden Sie feedback im Repository MicrosoftDocs/edge-developer.

Schema der .heapsnapshot Daten

Struktur der obersten Ebene

Die .heapsnapshot JSON-Daten enthalten ein Stammobjekt mit den folgenden Eigenschaften:

{
    "snapshot": {},
    "nodes": [],
    "edges": [],
    "trace_function_infos": [],
    "trace_tree": [],
    "samples": [],
    "locations": [],
    "strings": []
}
Eigenschaft Beschreibung Format
snapshot Enthält alle Informationen zum Format der Speicherdiagrammdaten und deren Größe. Object
nodes Alle Informationen, die erforderlich sind, um die Knoten des Graphen neu zu erstellen. Um diese Daten zu analysieren, verwenden Sie snapshot.meta.node_types und snapshot.meta.node_fields. Array
edges Alle Informationen, die erforderlich sind, um die Kanten des Graphen neu zu erstellen. Um diese Daten zu analysieren, verwenden Sie snapshot.meta.edge_types und snapshot.meta.edge_fields. Array
trace_function_infos Noch nicht dokumentiert Array
trace_tree Noch nicht dokumentiert Array
samples Noch nicht dokumentiert Array
locations Enthält Informationen zum Skriptspeicherort von Knoten. Verwenden Sie snapshot.meta.location_fields zum Analysieren dieser Daten mit dem nodes Array. Array
strings Ein Array aller Zeichenfolgen, die im Arbeitsspeicher gespeichert sind. Dabei kann es sich um beliebige Zeichenfolgen handeln, z. B. benutzerdefinierte Zeichenfolgen oder Code. Array

Snapshot

{
    "snapshot": {     
        "meta": {},
        "node_count": 123,
        "edge_count": 456,
        "trace_function_count": 0
    }
    ...
}
Eigenschaft Beschreibung Format
meta Eigenschaften, die Informationen zur Form und Größe jedes Objekts enthalten, das in den Speicherdiagrammdaten enthalten ist. Object
node_count Die Gesamtanzahl der Knoten im Speicherdiagramm. Number
edge_count Die Gesamtanzahl der Kanten im Speicherdiagramm. Number
trace_function_count Die Gesamtanzahl der Ablaufverfolgungsfunktionen im Speicherdiagramm. Number

Momentaufnahmemetadaten

{
    "snapshot": {
        "meta": {
            "node_fields": [],
            "node_types": [],
            "edge_fields": [],
            "edge_types": []
        }
    }
    ...
}
Eigenschaft Beschreibung Format
node_fields Die Liste aller Eigenschaften, die zum erneuten Erstellen eines Knotens erforderlich sind. Array
node_types Die Typen aller Eigenschaften, die zum erneuten Erstellen eines Knotens erforderlich sind. Die Anzahl der Typen entspricht der Anzahl der in node_fieldsdefinierten Eigenschaften. Array
edge_fields Die Liste aller Eigenschaften, die zum erneuten Erstellen eines Edges erforderlich sind. Array
edge_types Die Typen aller Eigenschaften, die zum erneuten Erstellen eines Edges erforderlich sind. Die Anzahl der Typen entspricht der Anzahl der Eigenschaften in edge_fields. Array

Es folgt ein Beispiel für ein Metadatenobjekt:

{
    "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

Das nodes Array, das sich auf der obersten Ebene der .heapsnapshot Daten befindet, enthält alle Informationen, die erforderlich sind, um die Knoten des Speicherdiagramms neu zu erstellen.

Zum Analysieren dieses Arrays sind die folgenden Informationen erforderlich:

  • snapshot.node_count, um zu wissen, wie viele Knoten es gibt.
  • snapshot.meta.node_fields, um zu wissen, über wie viele Felder jeder Knoten verfügt.

Jeder Knoten im Array wird durch eine Reihe von snapshot.meta.node_fields.length Zahlen dargestellt. Die Gesamtzahl der Elemente im nodes Array wird snapshot.node_count also mit snapshot.meta.node_fields.lengthmultipliziert.

Um einen Knoten neu zu erstellen, lesen Sie die Zahlen aus dem nodes Array nach Gruppen der Größe snapshot.meta.node_fields.length.

Der folgende Codeausschnitt zeigt die node_fields Metadaten und die Daten für die ersten beiden Knoten im Diagramm:

{
    "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,
        ...
    ]
    ...
}
Index in Knotengruppe Name Beschreibung
0 type Der Typ des Knotens. Weitere Informationen finden Sie weiter unten unter Knotentypen.
1 name Der Name des Knotens. Dies ist eine Zahl, die den Index im Array der obersten Ebene strings darstellt. Um den tatsächlichen Namen zu finden, verwenden Sie die Indexnummer, um die Zeichenfolge im Array der obersten Ebene strings nachzuschlagen.
2 id Die eindeutige ID des Knotens.
3 self_size Die Größe des Knotens in Bytes.
4 edge_count Die Anzahl von Edges, die mit diesem Knoten verbunden sind.
5 trace_node_id Die ID des Ablaufverfolgungsknotens
6 detachedness Gibt an, ob dieser Knoten vom globalen Objekt aus window erreicht werden kann. 0 bedeutet, dass der Knoten nicht getrennt ist; Der Knoten kann vom globalen Objekt aus window erreicht werden. 1 bedeutet, dass der Knoten getrennt ist; Der Knoten kann vom window globalen Objekt nicht erreicht werden.

Knotentypen

Die erste Zahl in der Gruppe von Zahlen für einen Knoten im nodes Array entspricht ihrem Typ. Diese Zahl ist ein Index, der verwendet werden kann, um den Typnamen im snapshot.meta.node_types[0] Array zu suchen.

Knotentyp Beschreibung
Ausgeblendet Ein internes V8-Element, das nicht direkt einem vom Benutzer steuerbaren JavaScript-Objekt entspricht. In DevTools werden diese unter dem Kategorienamen (System) angezeigt. Obwohl diese Objekte intern sind, können sie ein wichtiger Bestandteil von Aufbewahrungspfaden sein.
Objekt Jedes benutzerdefinierte Objekt, z { x: 2 } . B. oder new Foo(4). Kontexte, die in DevTools als System/Kontext angezeigt werden, enthalten Variablen, die auf dem Heap zugeordnet werden mussten, da sie von einer geschachtelten Funktion verwendet werden.
Systemeigen Elemente, die von der Blink-Rendering-Engine und nicht von V8 zugeordnet werden. Dies sind hauptsächlich DOM-Elemente wie HTMLDivElement oder CSSStyleRule.
Verkettete Zeichenfolge Das Ergebnis der Verkettung von zwei Zeichenfolgen mit dem + Operator. Anstatt eine neue Zeichenfolge zu erstellen, die eine Kopie aller Daten aus den beiden Quellzeichenfolgen enthält, erstellt V8 ein ConsString -Objekt, das Zeiger auf die beiden Quellzeichenfolgen enthält. Aus JavaScript-Sicht verhält es sich wie jede andere Zeichenfolge, aber aus Sicht der Speicherprofilerstellung ist es anders.
Zeichenfolge mit Datenschnitt Das Ergebnis einer Teilzeichenfolgenoperation, z. B. mit String.prototype.substr oder String.prototype.substring. V8 vermeidet das Kopieren von Zeichenfolgendaten, indem stattdessen ein SlicedStringerstellt wird, der auf die ursprüngliche Zeichenfolge verweist und den Anfangsindex und die Länge angibt. Aus JavaScript-Sicht verhält sich eine Zeichenfolge mit Datenschnitt wie jede andere Zeichenfolge, aber aus Sicht der Speicherprofilerstellung ist sie anders.
Array Verschiedene interne Listen, die in DevTools mit dem Kategorienamen (Array) angezeigt werden. Wie Ausgeblendet gruppiert diese Kategorie eine Vielzahl von Dingen. Viele der hier aufgeführten Objekte sind benannt (Objekteigenschaften) oder (Objektelemente), was angibt, dass sie die Eigenschaften mit Zeichenfolgenschlüssel oder numerischen Schlüsseln eines JavaScript-Objekts enthalten.
Code Dinge, die proportional zur Menge des Skripts und/oder zur Häufigkeit der Ausführung von Funktionen wachsen.
Synthetisch Synthetische Knoten entsprechen nichts, was tatsächlich im Arbeitsspeicher zugeordnet ist. Diese werden verwendet, um die verschiedenen Arten von Garbage Collection-Wurzeln (GC) zu unterscheiden.

Kanten

Ähnlich wie das nodes -Array enthält das Array der edges obersten Ebene alle Elemente, die zum neu erstellen der Ränder des Speicherdiagramms erforderlich sind.

Ähnlich wie bei Knoten kann die Gesamtanzahl der Kanten durch Multiplizieren snapshot.edge_count mit snapshot.meta.edge_fields.lengthberechnet werden. Kanten werden auch als Sequenz von Zahlen gespeichert, die Sie nach Gruppen der Größe snapshot.meta.edge_fields.lengthdurchlaufen müssen.

Um das edges Array richtig zu lesen, müssen Sie jedoch zuerst das nodes Array lesen, da jeder Knoten weiß, wie viele Kanten er hat.

Um einen Edge neu zu erstellen, benötigen Sie drei Informationen:

  • Der Edgetyp.
  • Der Edgename oder -index.
  • Der Knoten, mit dem der Edge verbunden ist.

Wenn Sie z. B. den ersten Knoten im nodes Array lesen und dessen edge_count Eigenschaft auf 4 festgelegt ist, entsprechen die ersten vier Zahlengruppen snapshot.meta.edge_fields.length im edges Array den vier Kanten dieses Knotens.

Index in Edgegruppe Name Beschreibung
0 type Der Typ des Edges. Informationen zu den möglichen Typen finden Sie unter Edgetypen .
1 name_or_index Dies kann eine Zahl oder eine Zeichenfolge sein. Wenn es sich um eine Zahl handelt, entspricht sie dem Index im Array der obersten Ebene strings , in dem der Name des Edges gefunden werden kann.
2 to_node Der Index innerhalb des nodes Arrays, mit dem dieser Edge verbunden ist.

Edgetypen

Die erste Zahl in der Gruppe von Zahlen für eine Kante im edges Array entspricht ihrem Typ. Diese Zahl ist ein Index, der verwendet werden kann, um den Typnamen im snapshot.meta.edge_types[0] Array zu suchen.

Edgetyp Beschreibung
Intern Kanten, die nicht mit JavaScript sichtbaren Namen übereinstimmen, aber dennoch wichtig sind. Funktionsinstanzen verfügen beispielsweise über einen "Kontext", der den Zustand von Variablen darstellt, die sich im Bereich befanden, in dem die Funktion definiert wurde. Es gibt keine Möglichkeit für JavaScript-Code, den "Kontext" einer Funktion direkt zu lesen, aber diese Kanten sind für die Untersuchung von Aufbewahrungen erforderlich.
Schwach Schwache Kanten halten den Knoten, mit dem sie verbunden sind, nicht aktiv und werden daher in der Ansicht Aufbewahrungen ausgelassen. Jedes Objekt mit nur schwachen Kanten, die darauf verweisen, kann von der Garbage Collection (GC) verworfen werden.
Ausgeblendet Ähnlich wie intern, mit der Ausnahme, dass diese Kanten keine eindeutigen Namen haben und stattdessen in zunehmender Reihenfolge nummeriert werden.
Verknüpfung Eine einfacher zu lesende Darstellung eines anderen Pfads. Dieser Typ wird selten verwendet. Wenn Sie beispielsweise verwenden Function.prototype.bind , um eine gebundene Funktion mit einigen gebundenen Argumenten zu erstellen, erstellt V8 ein JSBoundFunction, das auf ein FixedArray (einen internen Typ) zeigt, der auf jedes gebundene Argument verweist. Beim Erstellen eines Momentaufnahme fügt V8 jedem gebundenen Argument eine Verknüpfungskante aus der gebundenen Funktion direkt hinzu, wobei das umgangen wirdFixedArray.
Element Objekteigenschaften, bei denen der Schlüssel eine Zahl ist.

locations

Das locations Array, das sich auf der obersten Ebene der .heapsnapshot Daten befindet, enthält Informationen darüber, wo einige der Knoten im Momentaufnahme erstellt wurden. Dieses Array besteht aus einer Reihe von Zahlen, die von Gruppen der Größe snapshot.meta.location_fields.lengthgelesen werden sollen. Daher würden wir zu snapshot.meta.location_fields gehen, um zu wissen, wie viele Felder jeder Standort im locations Array hat und was diese Felder sind. Wenn location_fields beispielsweise 4 Elemente enthalten sind, sollte das locations Array von Gruppen von 4 gelesen werden.

snapshot.meta.location_fields enthält die Informationen für jeden Speicherort:

Index in location_fields Name Beschreibung
0 object_index Der Index des Knotens in dem snapshot.nodes Array, das dieser Position zugeordnet ist.
1 script_id Die ID des Skripts, das den zugeordneten Knoten erstellt.
2 line Die Zeilennummer, in der der Knoten innerhalb des Skripts erstellt wurde, mit dem der Knoten erstellt wurde.
3 column Die Spaltennummer, in der der Knoten innerhalb des Skripts erstellt wurde, mit dem der Knoten erstellt wurde.

Im folgenden Codebeispiel wird gezeigt, wie das snapshot.locations Array mit dem snapshot.nodes Array verknüpft wird:

{
    "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,
        ...
    ],
    ...
}

Die erste Position im locations Array ist 7,9,0,0,. Dieser Speicherort ist der Knoteninformationsgruppe zugeordnet, die bei Index 7 im nodes Array beginnt. Daher enthält der Knoten die folgenden Schlüssel-Wert-Paare:

"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,

Siehe auch

Weitere Informationen zum .heapsnapshot Dateiformat finden Sie im Code, der die Datei generiert. Dabei handelt es sich um die HeapSnapshotGenerator -Klasse in heap-snapshot-generator.h.