Heap-snapshots opnemen, Heap-snapshots opnemen

Meggin Kearney
Meggin Kearney
Sofia Emelianova
Sofia Emelianova

Leer hoe u heap-snapshots kunt opnemen met Geheugen > Profielen > Heap-snapshot en hoe u geheugenlekken kunt opsporen.

De heap profiler toont de geheugenverdeling door de JavaScript-objecten van uw pagina en gerelateerde DOM-knooppunten. Gebruik het om JS-heap-snapshots te maken, geheugengrafieken te analyseren, snapshots te vergelijken en geheugenlekken te vinden. Zie Objecten die de structuur behouden voor meer informatie.

Maak een momentopname

Een heap-snapshot maken:

  1. Op een pagina die u wilt profileren, opent u DevTools en navigeert u naar het paneel Geheugen .
  2. Selecteer het Heap snapshot -profileringstype, selecteer vervolgens een JavaScript VM-instantie en klik op Momentopname maken .

Een geselecteerd profileringstype en JavaScript VM-instantie.

Wanneer het paneel Geheugen de momentopname laadt en parseert, wordt de totale grootte van bereikbare JavaScript-objecten weergegeven onder de titel van de momentopname in de sectie HEAP SNAPSHOTS .

De totale grootte van bereikbare objecten.

Snapshots tonen alleen de objecten uit de geheugengrafiek die bereikbaar zijn vanuit het globale object. Het maken van een momentopname begint altijd met het verzamelen van afval.

Een heap-momentopname van verspreide Item-objecten.

Duidelijke momentopnamen

Om alle snapshots te verwijderen, klikt u op Alle profielen wissen :

Wis alle profielen.

Bekijk momentopnamen

Om snapshots vanuit verschillende perspectieven voor verschillende doeleinden te bekijken, selecteert u een van de weergaven in het vervolgkeuzemenu bovenaan:

Weergave Inhoud Doel
Samenvatting Objecten gegroepeerd op constructornamen en bronnen. Gebruik het om objecten en hun geheugengebruik op te sporen op basis van type. Handig voor het opsporen van DOM-lekken .
Vergelijking Verschillen tussen twee momentopnamen. Gebruik het om twee (of meer) snapshots te vergelijken, voor en na een operatie. Bevestig de aanwezigheid en oorzaak van een geheugenlek door de delta in het vrijgemaakte geheugen en het aantal referenties te inspecteren.
Insluiting Hoop inhoud Biedt een beter zicht op de objectstructuur en helpt bij het analyseren van objecten waarnaar wordt verwezen in de globale naamruimte (venster) om te ontdekken wat ze in de buurt houdt. Gebruik het om afsluitingen te analyseren en op een laag niveau in uw objecten te duiken.
Statistieken Cirkeldiagram van geheugentoewijzing Bekijk de reële grootte van geheugenonderdelen die zijn toegewezen aan code, tekenreeksen, JS-arrays, getypte arrays en systeemobjecten.

De Samenvattingsweergave geselecteerd in het vervolgkeuzemenu bovenaan.

Samenvatting weergave

In eerste instantie wordt er een heap-momentopname geopend in de overzichtsweergave , waarin constructors in een kolom worden vermeld. Constructors zijn genoemd naar de JavaScript-functie die het object heeft gemaakt, de namen van gewone objecten zijn gebaseerd op de juiste naam die ze bevatten, en sommige namen zijn speciale vermeldingen . Alle objecten worden eerst gegroepeerd op hun naam en vervolgens op de regel in het bronbestand waar ze vandaan komen, bijvoorbeeld source-file.js:line-number .

U kunt gegroepeerde constructors uitvouwen om de objecten te zien die ze hebben geïnstantieerd.

De Samenvatting-weergave met een uitgebreide constructor.

Om irrelevante constructors eruit te filteren, typt u een naam die u wilt inspecteren in het Klassefilter bovenaan de Samenvattingsweergave .

De cijfers naast de constructornamen geven het totale aantal objecten aan dat met de constructor is gemaakt. In de samenvattingsweergave worden ook de volgende kolommen weergegeven:

  • Afstand toont de afstand tot de wortel met behulp van het kortste eenvoudige pad van knooppunten.
  • Ondiep formaat toont de som van de ondiepe afmetingen van alle objecten die door een bepaalde constructor zijn gemaakt. De ondiepe grootte is de grootte van het geheugen dat door een object zelf wordt vastgehouden. Over het algemeen hebben arrays en strings grotere ondiepe afmetingen. Zie ook Objectgroottes .
  • Ingehouden grootte toont de maximaal behouden grootte voor dezelfde set objecten. De behouden grootte is de grootte van het geheugen dat u kunt vrijmaken door een object te verwijderen en de afhankelijke objecten ervan niet langer bereikbaar te maken. Zie ook Objectgroottes .

Wanneer u een constructor uitvouwt, toont de overzichtsweergave alle exemplaren ervan. Elke instantie krijgt een uitsplitsing van de ondiepe en behouden afmetingen in de overeenkomstige kolommen. Het getal na het @ -teken is de unieke ID van het object. Hiermee kunt u heap-snapshots per object vergelijken.

Constructorfilters

Met de overzichtsweergave kunt u constructors filteren op basis van veelvoorkomende gevallen van inefficiënt geheugengebruik.

Om deze filters te gebruiken, selecteert u een van de volgende opties in het meest rechtse vervolgkeuzemenu op de actiebalk:

  • Alle objecten : alle objecten die zijn vastgelegd door de huidige momentopname. Standaard ingesteld.
  • Objecten toegewezen vóór momentopname 1 : objecten die zijn gemaakt en in het geheugen zijn gebleven voordat de eerste momentopname werd gemaakt.
  • Objecten toegewezen tussen Snapshots 1 en Snapshots 2 : bekijk het verschil in objecten tussen de meest recente snapshot en de vorige snapshot. Elke nieuwe momentopname voegt een verhoging van dit filter toe aan de vervolgkeuzelijst.
  • Gedupliceerde strings : stringwaarden die meerdere keren in het geheugen zijn opgeslagen.
  • Objecten die worden vastgehouden door losgemaakte knooppunten : objecten die in leven worden gehouden omdat een losgemaakt DOM-knooppunt ernaar verwijst.
  • Objecten die worden bewaard door de DevTools-console : objecten die in het geheugen worden bewaard omdat ze zijn geëvalueerd of interactie hebben gehad via de DevTools-console.

Speciale vermeldingen in Samenvatting

Naast het groeperen op constructors, groepeert de Samenvattingsweergave ook objecten op:

  • Ingebouwde functies zoals Array of Object .
  • HTML-elementen gegroepeerd op hun tags, bijvoorbeeld <div> , <a> , <img> en andere.
  • Functies die u in uw code hebt gedefinieerd.
  • Speciale categorieën die niet op constructors zijn gebaseerd.

Inzendingen voor constructeurs.

(array)

Deze categorie bevat verschillende interne array-achtige objecten die niet direct overeenkomen met objecten die zichtbaar zijn in JavaScript.

De inhoud van JavaScript Array -objecten wordt bijvoorbeeld opgeslagen in een secundair intern object met de naam (object elements)[] , zodat het formaat gemakkelijker kan worden aangepast. Op dezelfde manier worden de benoemde eigenschappen in JavaScript-objecten vaak opgeslagen in secundaire interne objecten met de naam (object properties)[] die ook worden vermeld in de categorie (array) .

(compiled code)

Deze categorie bevat interne gegevens die V8 nodig heeft zodat functies kunnen worden uitgevoerd die zijn gedefinieerd door JavaScript of WebAssembly. Elke functie kan op verschillende manieren worden weergegeven, van klein en langzaam tot groot en snel.

V8 beheert automatisch het geheugengebruik in deze categorie. Als een functie vele malen wordt uitgevoerd, gebruikt V8 meer geheugen voor die functie, zodat deze sneller kan worden uitgevoerd. Als een functie al een tijdje niet is uitgevoerd, kan V8 de interne gegevens voor die functie wissen.

(concatenated string)

Wanneer V8 twee strings aaneenschakelt, zoals met de JavaScript + operator, kan het ervoor kiezen om het resultaat intern weer te geven als een "aaneengeschakelde string", ook wel bekend als de Rope -datastructuur.

In plaats van alle karakters van de twee bronstrings naar een nieuwe string te kopiëren, wijst V8 een klein object toe met interne velden genaamd first en second , die naar de twee bronstrings verwijzen. Hierdoor kan V8 tijd en geheugen besparen. Vanuit het perspectief van JavaScript-code zijn dit gewoon normale tekenreeksen en gedragen ze zich als elke andere tekenreeks.

InternalNode

Deze categorie vertegenwoordigt objecten die buiten V8 zijn toegewezen, zoals C++-objecten gedefinieerd door Blink .

Om C++-klassenamen te zien, gebruikt u Chrome for Testing en doet u het volgende:

  1. Open DevTools en schakel in Instellingen > Experimenten > Optie weergeven om internals bloot te leggen in heap-snapshots .
  2. Open het paneel Geheugen , selecteer Heap snapshot en schakel Expose internals in (bevat aanvullende implementatiespecifieke details) .
  3. Reproduceer het probleem waardoor de InternalNode veel geheugen vasthield.
  4. Maak een heap-snapshot. In deze momentopname hebben objecten C++-klassenamen in plaats van InternalNode .
(object shape)

Zoals beschreven in Snelle eigenschappen in V8 , volgt V8 verborgen klassen (of vormen ) zodat meerdere objecten met dezelfde eigenschappen in dezelfde volgorde efficiënt kunnen worden weergegeven. Deze categorie bevat de verborgen klassen, genaamd system / Map (niet gerelateerd aan JavaScript Map ), en gerelateerde gegevens.

(sliced string)

Wanneer V8 een substring moet gebruiken, zoals wanneer JavaScript-code String.prototype.substring() aanroept, kan V8 ervoor kiezen om een ​​gesegmenteerd stringobject toe te wijzen in plaats van alle relevante tekens uit de originele string te kopiëren. Dit nieuwe object bevat een verwijzing naar de originele string en beschrijft welk bereik van tekens uit de originele string moet worden gebruikt.

Vanuit het perspectief van JavaScript-code zijn dit gewoon normale tekenreeksen en gedragen ze zich als elke andere tekenreeks. Als een gesegmenteerde string veel geheugen vasthoudt, heeft het programma mogelijk probleem 2869 geactiveerd en kan het baat hebben bij het nemen van doelbewuste stappen om de gesegmenteerde string "af te vlakken".

system / Context

Interne objecten van het type system / Context bevatten lokale variabelen van een afsluiting : een JavaScript-scope waartoe een geneste functie toegang heeft.

Elke functie-instantie bevat een interne verwijzing naar de Context waarin deze wordt uitgevoerd, zodat deze toegang heeft tot die variabelen. Hoewel Context objecten niet direct zichtbaar zijn vanuit JavaScript, heeft u er wel directe controle over.

(system)

Deze categorie bevat verschillende interne objecten die (nog) niet op een betekenisvollere manier zijn gecategoriseerd.

Vergelijkingsweergave

In de vergelijkingsweergave kunt u gelekte objecten vinden door meerdere snapshots met elkaar te vergelijken. Als u bijvoorbeeld een actie uitvoert en deze ongedaan maakt, zoals het openen en sluiten van een document, mogen er geen extra objecten achterblijven.

Om te verifiëren dat een bepaalde bewerking geen lekken veroorzaakt:

  1. Maak een heap-snapshot voordat u een bewerking uitvoert.
  2. Voer een bewerking uit. Dat wil zeggen: interactie met een pagina op een manier waarvan u denkt dat deze een lek veroorzaakt.
  3. Voer een omgekeerde handeling uit. Dat wil zeggen, voer de tegenovergestelde interactie uit en herhaal deze een paar keer.
  4. Maak een tweede heap-snapshot en wijzig de weergave in Vergelijking , waarbij u deze vergelijkt met Snapshot 1 .

De vergelijkingsweergave toont het verschil tussen twee momentopnamen. Bij het uitvouwen van een totaalinvoer worden toegevoegde en verwijderde objectinstanties weergegeven:

Vergelijkbaar met momentopname 1.

Insluitingsweergave

De Containment- weergave is een 'vogelperspectief' van de objectstructuur van uw toepassing. Hiermee kunt u in functieafsluitingen kijken, interne VM-objecten observeren die samen uw JavaScript-objecten vormen, en begrijpen hoeveel geheugen uw applicatie op een zeer laag niveau gebruikt.

De weergave biedt verschillende toegangspunten:

  • DOMWindow-objecten . Globale objecten voor JavaScript-code.
  • GC-wortels . GC-roots gebruikt door de garbage collector van de VM. GC-roots kunnen bestaan ​​uit ingebouwde objectkaarten, symbooltabellen, VM-threadstacks, compilatiecaches, handle-scopes en globale handvatten.
  • Inheemse objecten . Browserobjecten worden in de virtuele JavaScript-machine 'gepusht' om automatisering mogelijk te maken, bijvoorbeeld DOM-knooppunten en CSS-regels.

De insluitingsweergave.

Het gedeelte Vasthouders

In het gedeelte Vasthouders onder aan het deelvenster Geheugen worden objecten weergegeven die verwijzen naar het object dat in de weergave is geselecteerd. Het paneel Geheugen werkt de sectie Vasthouders bij wanneer u een ander object selecteert in een van de weergaven behalve Statistieken .

Het gedeelte Vasthouders.

In dit voorbeeld wordt de geselecteerde tekenreeks behouden door de x eigenschap van een Item instantie.

Negeer houders

U kunt vasthouders verbergen om te zien of andere objecten de geselecteerde behouden. Met deze optie hoeft u deze houder niet eerst uit de code te verwijderen en vervolgens de heap-snapshot opnieuw te maken.

De optie 'Deze retentie negeren' in het vervolgkeuzemenu.

Als u een houder wilt verbergen, klikt u met de rechtermuisknop en selecteert u Deze houder negeren . Genegeerde vasthouders worden gemarkeerd als ignored in de kolom Afstand . Als u wilt stoppen met het negeren van alle vasthouders, klikt u op Genegeerde vasthouders herstellen in de actiebalk bovenaan.

Zoek een specifiek object

Om een ​​object in de verzamelde heap te vinden, kunt u zoeken met Ctrl + F en de object-ID invoeren.

Benoem functies om sluitingen te onderscheiden

Het helpt enorm om de functies een naam te geven, zodat je onderscheid kunt maken tussen sluitingen in de momentopname.

De volgende code maakt bijvoorbeeld geen gebruik van benoemde functies:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function() { // this is NOT a named function
    return largeStr;
  };

  return lC;
}

Hoewel dit voorbeeld het volgende doet:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function lC() { // this IS a named function
    return largeStr;
  };

  return lC;
}

Benoemde functie in een sluiting.

Ontdek DOM-lekken

De heap profiler heeft de mogelijkheid om bidirectionele afhankelijkheden tussen browser-native objecten (DOM-knooppunten en CSS-regels) en JavaScript-objecten weer te geven. Dit helpt bij het ontdekken van anders onzichtbare lekken die optreden als gevolg van vergeten, losgemaakte DOM-subbomen die rondzweven.

DOM-lekken kunnen groter zijn dan u denkt. Beschouw het volgende voorbeeld. Wanneer wordt het #tree opgehaald?

  var select = document.querySelector;
  var treeRef = select("#tree");
  var leafRef = select("#leaf");
  var body = select("body");

  body.removeChild(treeRef);

  //#tree can't be GC yet due to treeRef
  treeRef = null;

  //#tree can't be GC yet due to indirect
  //reference from leafRef

  leafRef = null;
  //#NOW #tree can be garbage collected

#leaf onderhoudt een verwijzing naar zijn ouder ( parentNode ) en recursief tot aan #tree , dus alleen wanneer leafRef teniet wordt gedaan, is de hele boom onder #tree een kandidaat voor GC.

DOM-subbomen

,

Meggin Kearney
Meggin Kearney
Sofia Emelianova
Sofia Emelianova

Leer hoe u heap-snapshots kunt opnemen met Geheugen > Profielen > Heap-snapshot en hoe u geheugenlekken kunt opsporen.

De heap profiler toont de geheugenverdeling door de JavaScript-objecten van uw pagina en gerelateerde DOM-knooppunten. Gebruik het om JS-heap-snapshots te maken, geheugengrafieken te analyseren, snapshots te vergelijken en geheugenlekken te vinden. Zie Objecten die de structuur behouden voor meer informatie.

Maak een momentopname

Een heap-snapshot maken:

  1. Op een pagina die u wilt profileren, opent u DevTools en navigeert u naar het paneel Geheugen .
  2. Selecteer het Heap snapshot -profileringstype, selecteer vervolgens een JavaScript VM-instantie en klik op Momentopname maken .

Een geselecteerd profileringstype en JavaScript VM-instantie.

Wanneer het paneel Geheugen de momentopname laadt en parseert, wordt de totale grootte van bereikbare JavaScript-objecten weergegeven onder de titel van de momentopname in de sectie HEAP SNAPSHOTS .

De totale grootte van bereikbare objecten.

Snapshots tonen alleen de objecten uit de geheugengrafiek die bereikbaar zijn vanuit het globale object. Het maken van een momentopname begint altijd met het verzamelen van afval.

Een heap-momentopname van verspreide Item-objecten.

Duidelijke momentopnamen

Om alle snapshots te verwijderen, klikt u op Alle profielen wissen :

Wis alle profielen.

Bekijk momentopnamen

Om snapshots vanuit verschillende perspectieven voor verschillende doeleinden te bekijken, selecteert u een van de weergaven in het vervolgkeuzemenu bovenaan:

Weergave Inhoud Doel
Samenvatting Objecten gegroepeerd op constructornamen en bronnen. Gebruik het om objecten en hun geheugengebruik op te sporen op basis van type. Handig voor het opsporen van DOM-lekken .
Vergelijking Verschillen tussen twee momentopnamen. Gebruik het om twee (of meer) snapshots te vergelijken, voor en na een operatie. Bevestig de aanwezigheid en oorzaak van een geheugenlek door de delta in het vrijgemaakte geheugen en het aantal referenties te inspecteren.
Insluiting Hoop inhoud Biedt een beter zicht op de objectstructuur en helpt bij het analyseren van objecten waarnaar wordt verwezen in de globale naamruimte (venster) om te ontdekken wat ze in de buurt houdt. Gebruik het om afsluitingen te analyseren en op een laag niveau in uw objecten te duiken.
Statistieken Cirkeldiagram van geheugentoewijzing Bekijk de reële grootte van geheugenonderdelen die zijn toegewezen aan code, tekenreeksen, JS-arrays, getypte arrays en systeemobjecten.

De Samenvattingsweergave geselecteerd in het vervolgkeuzemenu bovenaan.

Samenvatting weergave

In eerste instantie wordt er een heap-momentopname geopend in de overzichtsweergave , waarin constructors in een kolom worden vermeld. Constructors zijn genoemd naar de JavaScript-functie die het object heeft gemaakt, de namen van gewone objecten zijn gebaseerd op de juiste naam die ze bevatten, en sommige namen zijn speciale vermeldingen . Alle objecten worden eerst gegroepeerd op hun naam en vervolgens op de regel in het bronbestand waar ze vandaan komen, bijvoorbeeld source-file.js:line-number .

U kunt gegroepeerde constructors uitvouwen om de objecten te zien die ze hebben geïnstantieerd.

De Samenvatting-weergave met een uitgebreide constructor.

Om irrelevante constructors eruit te filteren, typt u een naam die u wilt inspecteren in het Klassefilter bovenaan de Samenvattingsweergave .

De cijfers naast de constructornamen geven het totale aantal objecten aan dat met de constructor is gemaakt. In de samenvattingsweergave worden ook de volgende kolommen weergegeven:

  • Afstand toont de afstand tot de wortel met behulp van het kortste eenvoudige pad van knooppunten.
  • Ondiep formaat toont de som van de ondiepe afmetingen van alle objecten die door een bepaalde constructor zijn gemaakt. De ondiepe grootte is de grootte van het geheugen dat door een object zelf wordt vastgehouden. Over het algemeen hebben arrays en strings grotere ondiepe afmetingen. Zie ook Objectgroottes .
  • Ingehouden grootte toont de maximaal behouden grootte voor dezelfde set objecten. De behouden grootte is de grootte van het geheugen dat u kunt vrijmaken door een object te verwijderen en de afhankelijke objecten ervan niet langer bereikbaar te maken. Zie ook Objectgroottes .

Wanneer u een constructor uitvouwt, toont de overzichtsweergave alle exemplaren ervan. Elke instantie krijgt een uitsplitsing van de ondiepe en behouden afmetingen in de overeenkomstige kolommen. Het getal na het @ -teken is de unieke ID van het object. Hiermee kunt u heap-snapshots per object vergelijken.

Constructorfilters

Met de overzichtsweergave kunt u constructors filteren op basis van veelvoorkomende gevallen van inefficiënt geheugengebruik.

Om deze filters te gebruiken, selecteert u een van de volgende opties in het meest rechtse vervolgkeuzemenu op de actiebalk:

  • Alle objecten : alle objecten die zijn vastgelegd door de huidige momentopname. Standaard ingesteld.
  • Objecten toegewezen vóór momentopname 1 : objecten die zijn gemaakt en in het geheugen zijn gebleven voordat de eerste momentopname werd gemaakt.
  • Objecten toegewezen tussen Snapshots 1 en Snapshots 2 : bekijk het verschil in objecten tussen de meest recente snapshot en de vorige snapshot. Elke nieuwe momentopname voegt een verhoging van dit filter toe aan de vervolgkeuzelijst.
  • Gedupliceerde strings : stringwaarden die meerdere keren in het geheugen zijn opgeslagen.
  • Objecten die worden vastgehouden door losgemaakte knooppunten : objecten die in leven worden gehouden omdat een losgemaakt DOM-knooppunt ernaar verwijst.
  • Objecten die worden bewaard door de DevTools-console : objecten die in het geheugen worden bewaard omdat ze zijn geëvalueerd of interactie hebben gehad via de DevTools-console.

Speciale vermeldingen in Samenvatting

Naast het groeperen op constructors, groepeert de Samenvattingsweergave ook objecten op:

  • Ingebouwde functies zoals Array of Object .
  • HTML-elementen gegroepeerd op hun tags, bijvoorbeeld <div> , <a> , <img> en andere.
  • Functies die u in uw code hebt gedefinieerd.
  • Speciale categorieën die niet op constructors zijn gebaseerd.

Inzendingen voor constructeurs.

(array)

Deze categorie bevat verschillende interne array-achtige objecten die niet direct overeenkomen met objecten die zichtbaar zijn in JavaScript.

De inhoud van JavaScript Array -objecten wordt bijvoorbeeld opgeslagen in een secundair intern object met de naam (object elements)[] , zodat het formaat gemakkelijker kan worden aangepast. Op dezelfde manier worden de benoemde eigenschappen in JavaScript-objecten vaak opgeslagen in secundaire interne objecten met de naam (object properties)[] die ook worden vermeld in de categorie (array) .

(compiled code)

Deze categorie bevat interne gegevens die V8 nodig heeft zodat functies kunnen worden uitgevoerd die zijn gedefinieerd door JavaScript of WebAssembly. Elke functie kan op verschillende manieren worden weergegeven, van klein en langzaam tot groot en snel.

V8 beheert automatisch het geheugengebruik in deze categorie. Als een functie vele malen wordt uitgevoerd, gebruikt V8 meer geheugen voor die functie, zodat deze sneller kan worden uitgevoerd. Als een functie al een tijdje niet is uitgevoerd, kan V8 de interne gegevens voor die functie wissen.

(concatenated string)

Wanneer V8 twee strings aaneenschakelt, zoals met de JavaScript + operator, kan het ervoor kiezen om het resultaat intern weer te geven als een "aaneengeschakelde string", ook wel bekend als de Rope -datastructuur.

In plaats van alle karakters van de twee bronstrings naar een nieuwe string te kopiëren, wijst V8 een klein object toe met interne velden genaamd first en second , die naar de twee bronstrings verwijzen. Hierdoor kan V8 tijd en geheugen besparen. Vanuit het perspectief van JavaScript-code zijn dit gewoon normale tekenreeksen en gedragen ze zich als elke andere tekenreeks.

InternalNode

Deze categorie vertegenwoordigt objecten die buiten V8 zijn toegewezen, zoals C++-objecten gedefinieerd door Blink .

Om C++-klassenamen te zien, gebruikt u Chrome for Testing en doet u het volgende:

  1. Open DevTools en schakel in Instellingen > Experimenten > Optie weergeven om internals bloot te leggen in heap-snapshots .
  2. Open het paneel Geheugen , selecteer Heap snapshot en schakel Expose internals in (bevat aanvullende implementatiespecifieke details) .
  3. Reproduceer het probleem waardoor de InternalNode veel geheugen vasthield.
  4. Maak een heap-snapshot. In deze momentopname hebben objecten C++-klassenamen in plaats van InternalNode .
(object shape)

Zoals beschreven in Snelle eigenschappen in V8 , volgt V8 verborgen klassen (of vormen ) zodat meerdere objecten met dezelfde eigenschappen in dezelfde volgorde efficiënt kunnen worden weergegeven. Deze categorie bevat de verborgen klassen, genaamd system / Map (niet gerelateerd aan JavaScript Map ), en gerelateerde gegevens.

(sliced string)

Wanneer V8 een substring nodig heeft, zoals wanneer JavaScript-code String.prototype.substring() aanroept, kan V8 ervoor kiezen om een ​​gesegmenteerd stringobject toe te wijzen in plaats van alle relevante tekens uit de originele string te kopiëren. Dit nieuwe object bevat een verwijzing naar de originele string en beschrijft welk bereik van tekens uit de originele string moet worden gebruikt.

Vanuit het perspectief van JavaScript-code zijn dit gewoon normale tekenreeksen en gedragen ze zich als elke andere tekenreeks. Als een gesegmenteerde string veel geheugen vasthoudt, heeft het programma mogelijk probleem 2869 geactiveerd en kan het baat hebben bij het nemen van doelbewuste stappen om de gesegmenteerde string "af te vlakken".

system / Context

Interne objecten van het type system / Context bevatten lokale variabelen van een afsluiting : een JavaScript-scope waartoe een geneste functie toegang heeft.

Elke functie-instantie bevat een interne verwijzing naar de Context waarin deze wordt uitgevoerd, zodat deze toegang heeft tot die variabelen. Hoewel Context objecten niet direct zichtbaar zijn vanuit JavaScript, heeft u er wel directe controle over.

(system)

Deze categorie bevat verschillende interne objecten die (nog) niet op een betekenisvollere manier zijn gecategoriseerd.

Vergelijkingsweergave

In de vergelijkingsweergave kunt u gelekte objecten vinden door meerdere snapshots met elkaar te vergelijken. Als u bijvoorbeeld een actie uitvoert en deze ongedaan maakt, zoals het openen en sluiten van een document, mogen er geen extra objecten achterblijven.

Om te verifiëren dat een bepaalde bewerking geen lekken veroorzaakt:

  1. Maak een heap-snapshot voordat u een bewerking uitvoert.
  2. Voer een bewerking uit. Dat wil zeggen: interactie met een pagina op een manier waarvan u denkt dat deze een lek veroorzaakt.
  3. Voer een omgekeerde handeling uit. Dat wil zeggen, voer de tegenovergestelde interactie uit en herhaal deze een paar keer.
  4. Maak een tweede heap-snapshot en wijzig de weergave in Vergelijking , waarbij u deze vergelijkt met Snapshot 1 .

De vergelijkingsweergave toont het verschil tussen twee momentopnamen. Bij het uitvouwen van een totaalinvoer worden toegevoegde en verwijderde objectinstanties weergegeven:

Vergelijkbaar met momentopname 1.

Insluitingsweergave

De Containment- weergave is een 'vogelperspectief' van de objectstructuur van uw toepassing. Hiermee kunt u in functieafsluitingen kijken, interne VM-objecten observeren die samen uw JavaScript-objecten vormen, en begrijpen hoeveel geheugen uw applicatie op een zeer laag niveau gebruikt.

De weergave biedt verschillende toegangspunten:

  • DOMWindow-objecten . Globale objecten voor JavaScript-code.
  • GC-wortels . GC-roots gebruikt door de garbage collector van de VM. GC-roots kunnen bestaan ​​uit ingebouwde objectkaarten, symbooltabellen, VM-threadstacks, compilatiecaches, handle-scopes en globale handvatten.
  • Inheemse objecten . Browserobjecten worden in de virtuele JavaScript-machine 'gepusht' om automatisering mogelijk te maken, bijvoorbeeld DOM-knooppunten en CSS-regels.

De insluitingsweergave.

Het gedeelte Vasthouders

In het gedeelte Vasthouders onder aan het deelvenster Geheugen worden objecten weergegeven die verwijzen naar het object dat in de weergave is geselecteerd. Het paneel Geheugen werkt de sectie Vasthouders bij wanneer u een ander object selecteert in een van de weergaven behalve Statistieken .

Het gedeelte Vasthouders.

In dit voorbeeld wordt de geselecteerde tekenreeks behouden door de x eigenschap van een Item instantie.

Negeer houders

U kunt vasthouders verbergen om te zien of andere objecten de geselecteerde behouden. Met deze optie hoeft u deze houder niet eerst uit de code te verwijderen en vervolgens de heap-snapshot opnieuw te maken.

De optie 'Deze retentie negeren' in het vervolgkeuzemenu.

Als u een houder wilt verbergen, klikt u met de rechtermuisknop en selecteert u Deze houder negeren . Genegeerde vasthouders worden gemarkeerd als ignored in de kolom Afstand . Als u wilt stoppen met het negeren van alle vasthouders, klikt u op Genegeerde vasthouders herstellen in de actiebalk bovenaan.

Zoek een specifiek object

Om een ​​object in de verzamelde heap te vinden, kunt u zoeken met Ctrl + F en de object-ID invoeren.

Benoem functies om sluitingen te onderscheiden

Het helpt enorm om de functies een naam te geven, zodat je onderscheid kunt maken tussen sluitingen in de momentopname.

De volgende code maakt bijvoorbeeld geen gebruik van benoemde functies:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function() { // this is NOT a named function
    return largeStr;
  };

  return lC;
}

Hoewel dit voorbeeld het volgende doet:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function lC() { // this IS a named function
    return largeStr;
  };

  return lC;
}

Benoemde functie in een sluiting.

Ontdek DOM-lekken

De heap profiler heeft de mogelijkheid om bidirectionele afhankelijkheden tussen browser-native objecten (DOM-knooppunten en CSS-regels) en JavaScript-objecten weer te geven. Dit helpt bij het ontdekken van anders onzichtbare lekken die optreden als gevolg van vergeten, losgemaakte DOM-subbomen die rondzweven.

DOM-lekken kunnen groter zijn dan u denkt. Beschouw het volgende voorbeeld. Wanneer wordt het #tree opgehaald?

  var select = document.querySelector;
  var treeRef = select("#tree");
  var leafRef = select("#leaf");
  var body = select("body");

  body.removeChild(treeRef);

  //#tree can't be GC yet due to treeRef
  treeRef = null;

  //#tree can't be GC yet due to indirect
  //reference from leafRef

  leafRef = null;
  //#NOW #tree can be garbage collected

#leaf onderhoudt een verwijzing naar zijn ouder ( parentNode ) en recursief tot aan #tree , dus alleen wanneer leafRef teniet wordt gedaan, is de hele boom onder #tree een kandidaat voor GC.

DOM-subbomen

,

Meggin Kearney
Meggin Kearney
Sofia Emelianova
Sofia Emelianova

Leer hoe u heap-snapshots kunt opnemen met Geheugen > Profielen > Heap-snapshot en hoe u geheugenlekken kunt opsporen.

De heap profiler toont de geheugenverdeling door de JavaScript-objecten van uw pagina en gerelateerde DOM-knooppunten. Gebruik het om JS-heap-snapshots te maken, geheugengrafieken te analyseren, snapshots te vergelijken en geheugenlekken te vinden. Zie Objecten die de structuur behouden voor meer informatie.

Maak een momentopname

Een heap-snapshot maken:

  1. Op een pagina die u wilt profileren, opent u DevTools en navigeert u naar het paneel Geheugen .
  2. Selecteer het Heap snapshot -profileringstype, selecteer vervolgens een JavaScript VM-instantie en klik op Momentopname maken .

Een geselecteerd profileringstype en JavaScript VM-instantie.

Wanneer het paneel Geheugen de momentopname laadt en parseert, wordt de totale grootte van bereikbare JavaScript-objecten weergegeven onder de titel van de momentopname in de sectie HEAP SNAPSHOTS .

De totale grootte van bereikbare objecten.

Snapshots tonen alleen de objecten uit de geheugengrafiek die bereikbaar zijn vanuit het globale object. Het maken van een momentopname begint altijd met het verzamelen van afval.

Een heap-momentopname van verspreide Item-objecten.

Duidelijke momentopnamen

Om alle snapshots te verwijderen, klikt u op Alle profielen wissen :

Wis alle profielen.

Bekijk momentopnamen

Om snapshots vanuit verschillende perspectieven voor verschillende doeleinden te bekijken, selecteert u een van de weergaven in het vervolgkeuzemenu bovenaan:

Weergave Inhoud Doel
Samenvatting Objecten gegroepeerd op constructornamen en bronnen. Gebruik het om objecten en hun geheugengebruik op te sporen op basis van type. Handig voor het opsporen van DOM-lekken .
Vergelijking Verschillen tussen twee momentopnamen. Gebruik het om twee (of meer) snapshots te vergelijken, voor en na een operatie. Bevestig de aanwezigheid en oorzaak van een geheugenlek door de delta in het vrijgemaakte geheugen en het aantal referenties te inspecteren.
Insluiting Hoop inhoud Biedt een beter zicht op de objectstructuur en helpt bij het analyseren van objecten waarnaar wordt verwezen in de globale naamruimte (venster) om te ontdekken wat ze in de buurt houdt. Gebruik het om afsluitingen te analyseren en op een laag niveau in uw objecten te duiken.
Statistieken Cirkeldiagram van geheugentoewijzing Bekijk de reële grootte van geheugenonderdelen die zijn toegewezen aan code, tekenreeksen, JS-arrays, getypte arrays en systeemobjecten.

De Samenvattingsweergave geselecteerd in het vervolgkeuzemenu bovenaan.

Samenvatting weergave

In eerste instantie wordt er een heap-momentopname geopend in de overzichtsweergave , waarin constructors in een kolom worden vermeld. Constructors zijn genoemd naar de JavaScript-functie die het object heeft gemaakt, de namen van gewone objecten zijn gebaseerd op de juiste naam die ze bevatten, en sommige namen zijn speciale vermeldingen . Alle objecten worden eerst gegroepeerd op hun naam en vervolgens op de regel in het bronbestand waar ze vandaan komen, bijvoorbeeld source-file.js:line-number .

U kunt gegroepeerde constructors uitvouwen om de objecten te zien die ze hebben geïnstantieerd.

De Samenvatting-weergave met een uitgebreide constructor.

Om irrelevante constructors eruit te filteren, typt u een naam die u wilt inspecteren in het Klassefilter bovenaan de Samenvattingsweergave .

De cijfers naast de constructornamen geven het totale aantal objecten aan dat met de constructor is gemaakt. In de samenvattingsweergave worden ook de volgende kolommen weergegeven:

  • Afstand toont de afstand tot de wortel met behulp van het kortste eenvoudige pad van knooppunten.
  • Ondiep formaat toont de som van de ondiepe afmetingen van alle objecten die door een bepaalde constructor zijn gemaakt. De ondiepe grootte is de grootte van het geheugen dat door een object zelf wordt vastgehouden. Over het algemeen hebben arrays en strings grotere ondiepe afmetingen. Zie ook Objectgroottes .
  • Ingehouden grootte toont de maximaal behouden grootte voor dezelfde set objecten. De behouden grootte is de grootte van het geheugen dat u kunt vrijmaken door een object te verwijderen en de afhankelijke objecten ervan niet langer bereikbaar te maken. Zie ook Objectgroottes .

Wanneer u een constructor uitvouwt, toont de overzichtsweergave alle exemplaren ervan. Elke instantie krijgt een uitsplitsing van de ondiepe en behouden afmetingen in de overeenkomstige kolommen. Het getal na het @ -teken is de unieke ID van het object. Hiermee kunt u heap-snapshots per object vergelijken.

Constructorfilters

Samenvatting View kunt u constructeurs filteren op basis van veel voorkomende gevallen van inefficiënt geheugengebruik.

Om deze filters te gebruiken, selecteert u een van de volgende opties uit het meest rechtse vervolgkeuzemenu in de actiebalk:

  • Alle objecten : alle objecten vastgelegd door de huidige momentopname. Standaard ingesteld.
  • Objecten toegewezen vóór Snapshot 1 : objecten die werden gemaakt en in het geheugen bleven voordat de eerste momentopname werd gemaakt.
  • Objecten toegewezen tussen snapshots 1 en snapshots 2 : Bekijk het verschil in objecten tussen de meest recente momentopname en de vorige momentopname. Elke nieuwe momentopname voegt een toename van dit filter toe aan de vervolgkeuzelijst.
  • Duplicated Strings : String -waarden die meerdere keren in het geheugen zijn opgeslagen.
  • Objecten behouden door losse knooppunten : objecten die in leven worden gehouden omdat een vrijstaande DOM -knooppunt verwijst.
  • Objecten behouden door de DevTools -console : objecten die in het geheugen worden bewaard omdat ze werden geëvalueerd of met interactie met de DevTools -console.

Speciale inzendingen in samenvatting

Naast groepering per constructors, groeit de samenvattende weergave ook objecten van:

  • Ingebouwde functies zoals Array of Object .
  • HTML -elementen gegroepeerd door hun tags, bijvoorbeeld <div> , <a> , <img> en anderen.
  • Functies die u in uw code hebt gedefinieerd.
  • Speciale categorieën die niet gebaseerd zijn op constructors.

Constructor -vermeldingen.

(array)

Deze categorie bevat verschillende interne arrayachtige objecten die niet direct overeenkomen met objecten die zichtbaar zijn in JavaScript.

De inhoud van JavaScript Array -objecten wordt bijvoorbeeld opgeslagen in een secundair intern object met de naam (object elements)[] , om gemakkelijker te wijzigen. Evenzo worden de genoemde eigenschappen in JavaScript -objecten vaak opgeslagen in secundaire interne objecten met de naam (object properties)[] die ook worden vermeld in de categorie (array) .

(compiled code)

Deze categorie bevat interne gegevens die V8 nodig hebben, zodat deze functies kunnen uitvoeren die zijn gedefinieerd door JavaScript of WebAssembly. Elke functie kan op verschillende manieren worden weergegeven, van klein en langzaam tot groot en snel.

V8 beheert automatisch geheugengebruik in deze categorie. Als een functie vele malen werkt, gebruikt V8 meer geheugen voor die functie zodat deze sneller kan worden uitgevoerd. Als een functie al een tijdje niet is uitgevoerd, kan V8 de interne gegevens voor die functie wissen.

(concatenated string)

Wanneer V8 twee snaren samenvoegt, zoals met de JavaScript + -operator, kan het ervoor kiezen om het resultaat intern weer te geven als een "samengevoegde string", ook bekend als de touwgegevensstructuur .

In plaats van alle tekens van de twee bronreeksen in een nieuwe string te kopiëren, wijst V8 een klein object toe met interne velden die first en second worden genoemd, die wijzen op de twee bronreeksen. Hiermee kunnen V8 tijd en geheugen besparen. Vanuit het perspectief van JavaScript -code zijn dit gewoon normale snaren, en ze gedragen zich als elke andere string.

InternalNode

Deze categorie vertegenwoordigt objecten die buiten V8 zijn toegewezen, zoals C ++ objecten gedefinieerd door knipperen .

Gebruik Chrome voor het testen en doe het volgende om C ++ klassennamen te bekijken:

  1. Open devtools en schakel in instellingen > Experimenten > weergeven optie om internals bloot te stellen in heap -snapshots .
  2. Open het geheugenpaneel , selecteer Heap Snapshot en schakel expose internals in (bevat extra implementatiespecifieke details) .
  3. Reproduceer het probleem dat ervoor zorgde dat de InternalNode veel geheugen behoudt.
  4. Maak een hoop momentopname. In deze momentopname hebben objecten C ++ klassennamen in plaats van InternalNode .
(object shape)

Zoals beschreven in snelle eigenschappen in V8 , volgt V8 verborgen klassen (of vormen ), zodat meerdere objecten met dezelfde eigenschappen in dezelfde volgorde efficiënt kunnen worden weergegeven. Deze categorie bevat die verborgen klassen, system / Map genaamd (niet gerelateerd aan JavaScript Map ) en gerelateerde gegevens.

(sliced string)

Wanneer V8 een substring moet nemen, zoals wanneer JavaScript -code String.prototype.substring() oproepen, kan V8 ervoor kiezen om een ​​gesneden stringobject toe te wijzen in plaats van alle relevante tekens uit de originele tekenreeks te kopiëren. Dit nieuwe object bevat een aanwijzer naar de originele tekenreeks en beschrijft welk bereik van tekens uit de originele tekenreeks moet worden gebruikt.

Vanuit het perspectief van JavaScript -code zijn dit gewoon normale snaren, en ze gedragen zich als elke andere string. Als een gesneden string veel geheugen behoudt, heeft het programma mogelijk probleem 2869 geactiveerd en kan het profiteren van het nemen van opzettelijke stappen om de gesneden snaar te "plat".

system / Context

Interne objecten van type system / Context bevatten lokale variabelen uit een sluiting - een JavaScript -scope waartoe een geneste functie toegang heeft.

Elke functie -instantie bevat een interne aanwijzer naar de Context waarin het wordt uitgevoerd, zodat deze toegang heeft tot die variabelen. Hoewel Context niet direct zichtbaar zijn van JavaScript, heb je er directe controle over.

(system)

Deze categorie bevat verschillende interne objecten die (nog) niet op een meer zinvolle manier zijn gecategoriseerd.

Vergelijkingsweergave

Met de vergelijkingsweergave kunt u gelekte objecten vinden door meerdere snapshots met elkaar te vergelijken. Bijvoorbeeld, een actie doen en omkeren, zoals het openen van een document en het sluiten ervan, mogen geen extra objecten achterlaten.

Om te controleren of een bepaalde bewerking geen lekken creëert:

  1. Maak een snapshot van een hoop voordat u een bewerking uitvoert.
  2. Een operatie uitvoeren. Dat wil zeggen, interactie met een pagina op de een of andere manier waarvan u denkt dat het een lek kan veroorzaken.
  3. Voer een omgekeerde bewerking uit. Dat wil zeggen, doe de tegenovergestelde interactie en herhaal het een paar keer.
  4. Maak een tweede hoop -momentopname en verander de weergave van de vergelijking en vergelijk deze met snapshot 1 .

De vergelijkingsweergave toont het verschil tussen twee snapshots. Bij het uitbreiden van een totale invoer worden toegevoegde en verwijderde objectinstanties getoond:

Vergelijking met snapshot 1.

Insluitingsweergave

Het insluitingsweergave is een "vogelweergave" van de structuur van uw applicatie. Hiermee kunt u in functieafsluitingen gluren, VM -interne objecten observeren die samen uw JavaScript -objecten vormen en om te begrijpen hoeveel geheugen uw toepassing op een zeer laag niveau gebruikt.

De weergave biedt verschillende toegangspunten:

  • Domwindow -objecten . Globale objecten voor JavaScript -code.
  • GC -wortels . GC -wortels die worden gebruikt door de afvalverzamelaar van de VM. GC-wortels kunnen bestaan ​​uit ingebouwde objectkaarten, symboltafels, VM-draadstapels, compilatiekachels, handgreepbereiken en globale handgrepen.
  • Native objecten . Browserobjecten "geduwd" in de virtuele JavaScript -machine om automatisering mogelijk te maken, bijvoorbeeld DOM -knooppunten en CSS -regels.

Het insluitingsweergave.

Het gedeelte van de houders

Het gedeelte Bewaarders onderaan het geheugenpaneel toont objecten die wijzen op het object dat in de weergave is geselecteerd. Het geheugenpaneel werkt het gedeelte met bewaarders bij wanneer u een andere objecten selecteert in een van de weergaven behalve statistieken .

Het gedeelte van de houders.

In dit voorbeeld wordt de geselecteerde tekenreeks vastgehouden door de x -eigenschap van een Item .

Negeer houders

U kunt houders verbergen om uit alle andere objecten de geselecteerde behouden te behouden. Met deze optie hoeft u deze houder niet eerst uit de code te verwijderen en vervolgens de heap -snapshot opnieuw te maken.

De optie 'Deze bewaarder negeren' in het vervolgkeuzemenu.

Om een ​​houder te verbergen, klikt u met de rechtermuisknop en selecteer deze deze houder te negeren . AGEGEERDE VINDERENDEREN worden gemarkeerd zoals ignored in de afstandskolom . Om te stoppen met het negeren van alle houders, klikt u op Restore genegeerde houders in de actiebalk bovenaan.

Zoek een specifiek object

Om een ​​object in de verzamelde heap te vinden, kunt u zoeken met Ctrl + F en de object -ID invoeren.

Naamfuncties om sluitingen te onderscheiden

Het helpt veel om de functies te noemen, zodat u onderscheid kunt maken tussen sluitingen in de momentopname.

De volgende code gebruikt bijvoorbeeld geen benoemde functies:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function() { // this is NOT a named function
    return largeStr;
  };

  return lC;
}

Terwijl dit voorbeeld doet:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function lC() { // this IS a named function
    return largeStr;
  };

  return lC;
}

Genoemde functie in een sluiting.

Ontdek Dom lekken

De Heap Profiler heeft de mogelijkheid om bidirectionele afhankelijkheden tussen browser-native objecten (DOM-knooppunten en CSS-regels) en JavaScript-objecten weer te geven. Dit helpt anders om anders onzichtbare lekken te ontdekken die plaatsvinden door vergeten vrijstaande DOM -substrees die rondzweven.

DOM -lekken kunnen groter zijn dan u denkt. Overweeg het volgende voorbeeld. Wanneer is de #tree -afval verzameld?

  var select = document.querySelector;
  var treeRef = select("#tree");
  var leafRef = select("#leaf");
  var body = select("body");

  body.removeChild(treeRef);

  //#tree can't be GC yet due to treeRef
  treeRef = null;

  //#tree can't be GC yet due to indirect
  //reference from leafRef

  leafRef = null;
  //#NOW #tree can be garbage collected

#leaf handhaaft een verwijzing naar zijn ouder ( parentNode ) en recursief tot #tree , dus alleen wanneer leafRef wordt vernietigd, is de hele boom onder #tree een kandidaat voor GC.

DOM -substrees

,

Meggin Kearney
Meggin Kearney
Sofia Emelianova
Sofia Emelianova

Leer hoe u heap -snapshots kunt opnemen met geheugen > Profielen > Snapshot heap en vind geheugenlekken.

De Heap Profiler toont geheugenverdeling door de JavaScript -objecten van uw pagina en gerelateerde DOM -knooppunten. Gebruik het om JS Heap Snapshots te maken, geheugengrafieken te analyseren, snapshots te vergelijken en geheugenlekken te vinden. Zie objecten voor meer informatie die de boom behoudt .

Maak een momentopname

Om een ​​hoop -momentopname te maken:

  1. Op een pagina die u wilt profileren, opent u devtools en navigeer ze naar het geheugenpaneel .
  2. Selecteer het Heap Snapshot -profileringstype en selecteer vervolgens een JavaScript VM -instantie en klik op Snapshot nemen .

Een geselecteerd profileringstype en JavaScript VM -instantie.

Wanneer het geheugenpaneel de momentopname laadt en parseert, toont dit de totale grootte van bereikbare JavaScript -objecten onder de Snapshot -titel in het gedeelte HEAP Snapshots .

De totale grootte van bereikbare objecten.

Snapshots tonen alleen de objecten uit de geheugengrafiek die bereikbaar zijn vanuit het globale object. Het maken van een momentopname begint altijd met afvalcollectie.

Een hoop momentopname van verspreide itemobjecten.

Wis op snapshots

Om alle snapshots te verwijderen, klikt u op alle profielen wissen :

Wis alle profielen.

Bekijk snapshots

Om snapshots vanuit verschillende perspectieven voor verschillende doeleinden te inspecteren, selecteert u een van de weergaven in het vervolgkeuzemenu bovenaan:

Weergave Inhoud Doel
Samenvatting Objecten gegroepeerd door constructornamen en bronnen. Gebruik het om objecten op te sporen en hun geheugengebruik op basis van het type. Nuttig voor het volgen van DOM -lekken .
Vergelijking Verschillen tussen twee snapshots. Gebruik het om twee (of meer) snapshots voor en na een bewerking te vergelijken. Bevestig de aanwezigheid en oorzaak van een geheugenlek door de delta te inspecteren in bevrijde geheugen en referentietelling.
Beheersing Heap -inhoud Biedt een beter beeld van de objectstructuur en helpt bij het analyseren van objecten waarnaar wordt verwezen in de Global NameSpace (venster) om te vinden wat ze in de buurt houdt. Gebruik het om sluitingen te analyseren en op een laag niveau in uw objecten te duiken.
Statistieken Cirkeldiagram van geheugentoewijzing Zie de realtive -formaten van geheugenonderdelen die zijn toegewezen aan code, strings, JS -arrays, getypte arrays en systeemobjecten.

De samenvattende weergave is geselecteerd in het vervolgkeuzemenu bovenaan.

Samenvatting Bekijk

Aanvankelijk opent een heap -snapshot in de samenvattende weergave die constructeurs in een kolom vermeldt. Constructeurs zijn vernoemd naar de JavaScript -functie die het object heeft gemaakt, namen van gewone objecten zijn gebaseerd op het juiste dat ze bevatten, en sommige namen zijn speciale vermeldingen . Alle objecten zijn eerst gegroepeerd door hun namen, vervolgens door de regel in het bronbestand waar ze uit komen, bijvoorbeeld source-file.js:line-number .

U kunt gegroepeerde constructeurs uitbreiden om de objecten te zien die ze hebben geïnstantieerd.

De samenvattende weergave met een uitgebreide constructor.

Typ een naam die u wilt inspecteren in het klassenfilter bovenaan de samenvattende weergave om irrelevante constructeurs uit te filteren.

De nummers naast de constructornamen geven het totale aantal objecten aan dat is gemaakt met de constructor. De samenvattende weergave toont ook de volgende kolommen:

  • Afstand toont de afstand tot de wortel met behulp van het kortste eenvoudige pad van knooppunten.
  • Ondiepe grootte toont de som van ondiepe maten van alle objecten die door een bepaalde constructor zijn gecreëerd. De ondiepe grootte is de grootte van het geheugen dat door een object zelf wordt gehouden. Over het algemeen hebben arrays en snaren grotere ondiepe maten. Zie ook objectgroottes .
  • Gehouden grootte toont de maximale vastgehouden grootte tussen dezelfde set objecten. Gehouden grootte is de grootte van het geheugen dat u kunt bevrijden door een object te verwijderen en de personen ten laste niet langer bereikbaar te maken. Zie ook objectgroottes .

Wanneer u een constructor uitbreidt, toont de samenvattende weergave u alle instanties. Elk exemplaar krijgt een uitsplitsing van zijn ondiepe en vastgehouden maten in de overeenkomstige kolommen. Het nummer na het @ -teken is de unieke ID van het object. Hiermee kunt u heap-snapshots vergelijken op basis van het object.

Constructorfilters

Samenvatting View kunt u constructeurs filteren op basis van veel voorkomende gevallen van inefficiënt geheugengebruik.

Om deze filters te gebruiken, selecteert u een van de volgende opties uit het meest rechtse vervolgkeuzemenu in de actiebalk:

  • Alle objecten : alle objecten vastgelegd door de huidige momentopname. Standaard ingesteld.
  • Objecten toegewezen vóór Snapshot 1 : objecten die werden gemaakt en in het geheugen bleven voordat de eerste momentopname werd gemaakt.
  • Objecten toegewezen tussen snapshots 1 en snapshots 2 : Bekijk het verschil in objecten tussen de meest recente momentopname en de vorige momentopname. Elke nieuwe momentopname voegt een toename van dit filter toe aan de vervolgkeuzelijst.
  • Duplicated Strings : String -waarden die meerdere keren in het geheugen zijn opgeslagen.
  • Objecten behouden door losse knooppunten : objecten die in leven worden gehouden omdat een vrijstaande DOM -knooppunt verwijst.
  • Objecten behouden door de DevTools -console : objecten die in het geheugen worden bewaard omdat ze werden geëvalueerd of met interactie met de DevTools -console.

Speciale inzendingen in samenvatting

Naast groepering per constructors, groeit de samenvattende weergave ook objecten van:

  • Ingebouwde functies zoals Array of Object .
  • HTML -elementen gegroepeerd door hun tags, bijvoorbeeld <div> , <a> , <img> en anderen.
  • Functies die u in uw code hebt gedefinieerd.
  • Speciale categorieën die niet gebaseerd zijn op constructors.

Constructor -vermeldingen.

(array)

Deze categorie bevat verschillende interne arrayachtige objecten die niet direct overeenkomen met objecten die zichtbaar zijn in JavaScript.

De inhoud van JavaScript Array -objecten wordt bijvoorbeeld opgeslagen in een secundair intern object met de naam (object elements)[] , om gemakkelijker te wijzigen. Evenzo worden de genoemde eigenschappen in JavaScript -objecten vaak opgeslagen in secundaire interne objecten met de naam (object properties)[] die ook worden vermeld in de categorie (array) .

(compiled code)

Deze categorie bevat interne gegevens die V8 nodig hebben, zodat deze functies kunnen uitvoeren die zijn gedefinieerd door JavaScript of WebAssembly. Elke functie kan op verschillende manieren worden weergegeven, van klein en langzaam tot groot en snel.

V8 beheert automatisch geheugengebruik in deze categorie. Als een functie vele malen werkt, gebruikt V8 meer geheugen voor die functie zodat deze sneller kan worden uitgevoerd. Als een functie al een tijdje niet is uitgevoerd, kan V8 de interne gegevens voor die functie wissen.

(concatenated string)

Wanneer V8 twee snaren samenvoegt, zoals met de JavaScript + -operator, kan het ervoor kiezen om het resultaat intern weer te geven als een "samengevoegde string", ook bekend als de touwgegevensstructuur .

In plaats van alle tekens van de twee bronreeksen in een nieuwe string te kopiëren, wijst V8 een klein object toe met interne velden die first en second worden genoemd, die wijzen op de twee bronreeksen. Hiermee kunnen V8 tijd en geheugen besparen. Vanuit het perspectief van JavaScript -code zijn dit gewoon normale snaren, en ze gedragen zich als elke andere string.

InternalNode

Deze categorie vertegenwoordigt objecten die buiten V8 zijn toegewezen, zoals C ++ objecten gedefinieerd door knipperen .

Gebruik Chrome voor het testen en doe het volgende om C ++ klassennamen te bekijken:

  1. Open devtools en schakel in instellingen > Experimenten > weergeven optie om internals bloot te stellen in heap -snapshots .
  2. Open het geheugenpaneel , selecteer Heap Snapshot en schakel expose internals in (bevat extra implementatiespecifieke details) .
  3. Reproduceer het probleem dat ervoor zorgde dat de InternalNode veel geheugen behoudt.
  4. Maak een hoop momentopname. In deze momentopname hebben objecten C ++ klassennamen in plaats van InternalNode .
(object shape)

Zoals beschreven in snelle eigenschappen in V8 , volgt V8 verborgen klassen (of vormen ), zodat meerdere objecten met dezelfde eigenschappen in dezelfde volgorde efficiënt kunnen worden weergegeven. Deze categorie bevat die verborgen klassen, system / Map genaamd (niet gerelateerd aan JavaScript Map ) en gerelateerde gegevens.

(sliced string)

Wanneer V8 een substring moet nemen, zoals wanneer JavaScript -code String.prototype.substring() oproepen, kan V8 ervoor kiezen om een ​​gesneden stringobject toe te wijzen in plaats van alle relevante tekens uit de originele tekenreeks te kopiëren. Dit nieuwe object bevat een aanwijzer naar de originele tekenreeks en beschrijft welk bereik van tekens uit de originele tekenreeks moet worden gebruikt.

Vanuit het perspectief van JavaScript -code zijn dit gewoon normale snaren, en ze gedragen zich als elke andere string. Als een gesneden string veel geheugen behoudt, heeft het programma mogelijk probleem 2869 geactiveerd en kan het profiteren van het nemen van opzettelijke stappen om de gesneden snaar te "plat".

system / Context

Interne objecten van type system / Context bevatten lokale variabelen uit een sluiting - een JavaScript -scope waartoe een geneste functie toegang heeft.

Elke functie -instantie bevat een interne aanwijzer naar de Context waarin het wordt uitgevoerd, zodat deze toegang heeft tot die variabelen. Hoewel Context niet direct zichtbaar zijn van JavaScript, heb je er directe controle over.

(system)

Deze categorie bevat verschillende interne objecten die (nog) niet op een meer zinvolle manier zijn gecategoriseerd.

Vergelijkingsweergave

Met de vergelijkingsweergave kunt u gelekte objecten vinden door meerdere snapshots met elkaar te vergelijken. Bijvoorbeeld, een actie doen en omkeren, zoals het openen van een document en het sluiten ervan, mogen geen extra objecten achterlaten.

Om te controleren of een bepaalde bewerking geen lekken creëert:

  1. Maak een snapshot van een hoop voordat u een bewerking uitvoert.
  2. Een operatie uitvoeren. Dat wil zeggen, interactie met een pagina op de een of andere manier waarvan u denkt dat het een lek kan veroorzaken.
  3. Voer een omgekeerde bewerking uit. Dat wil zeggen, doe de tegenovergestelde interactie en herhaal het een paar keer.
  4. Maak een tweede hoop -momentopname en verander de weergave van de vergelijking en vergelijk deze met snapshot 1 .

De vergelijkingsweergave toont het verschil tussen twee snapshots. Bij het uitbreiden van een totale invoer worden toegevoegde en verwijderde objectinstanties getoond:

Vergelijking met snapshot 1.

Insluitingsweergave

Het insluitingsweergave is een "vogelweergave" van de structuur van uw applicatie. Hiermee kunt u in functieafsluitingen gluren, VM -interne objecten observeren die samen uw JavaScript -objecten vormen en om te begrijpen hoeveel geheugen uw toepassing op een zeer laag niveau gebruikt.

De weergave biedt verschillende toegangspunten:

  • Domwindow -objecten . Globale objecten voor JavaScript -code.
  • GC -wortels . GC -wortels die worden gebruikt door de afvalverzamelaar van de VM. GC-wortels kunnen bestaan ​​uit ingebouwde objectkaarten, symboltafels, VM-draadstapels, compilatiekachels, handgreepbereiken en globale handgrepen.
  • Native objecten . Browserobjecten "geduwd" in de virtuele JavaScript -machine om automatisering mogelijk te maken, bijvoorbeeld DOM -knooppunten en CSS -regels.

Het insluitingsweergave.

Het gedeelte van de houders

Het gedeelte Bewaarders onderaan het geheugenpaneel toont objecten die wijzen op het object dat in de weergave is geselecteerd. Het geheugenpaneel werkt het gedeelte met bewaarders bij wanneer u een andere objecten selecteert in een van de weergaven behalve statistieken .

Het gedeelte van de houders.

In dit voorbeeld wordt de geselecteerde tekenreeks vastgehouden door de x -eigenschap van een Item .

Negeer houders

U kunt houders verbergen om uit alle andere objecten de geselecteerde behouden te behouden. Met deze optie hoeft u deze houder niet eerst uit de code te verwijderen en vervolgens de heap -snapshot opnieuw te maken.

De optie 'Deze bewaarder negeren' in het vervolgkeuzemenu.

Om een ​​houder te verbergen, klikt u met de rechtermuisknop en selecteer deze deze houder te negeren . AGEGEERDE VINDERENDEREN worden gemarkeerd zoals ignored in de afstandskolom . Om te stoppen met het negeren van alle houders, klikt u op Restore genegeerde houders in de actiebalk bovenaan.

Zoek een specifiek object

Om een ​​object in de verzamelde heap te vinden, kunt u zoeken met Ctrl + F en de object -ID invoeren.

Naamfuncties om sluitingen te onderscheiden

Het helpt veel om de functies te noemen, zodat u onderscheid kunt maken tussen sluitingen in de momentopname.

De volgende code gebruikt bijvoorbeeld geen benoemde functies:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function() { // this is NOT a named function
    return largeStr;
  };

  return lC;
}

Terwijl dit voorbeeld doet:

function createLargeClosure() {
  var largeStr = new Array(1000000).join('x');

  var lC = function lC() { // this IS a named function
    return largeStr;
  };

  return lC;
}

Genoemde functie in een sluiting.

Ontdek Dom lekken

De Heap Profiler heeft de mogelijkheid om bidirectionele afhankelijkheden tussen browser-native objecten (DOM-knooppunten en CSS-regels) en JavaScript-objecten weer te geven. Dit helpt anders om anders onzichtbare lekken te ontdekken die plaatsvinden door vergeten vrijstaande DOM -substrees die rondzweven.

DOM -lekken kunnen groter zijn dan u denkt. Overweeg het volgende voorbeeld. Wanneer is de #tree -afval verzameld?

  var select = document.querySelector;
  var treeRef = select("#tree");
  var leafRef = select("#leaf");
  var body = select("body");

  body.removeChild(treeRef);

  //#tree can't be GC yet due to treeRef
  treeRef = null;

  //#tree can't be GC yet due to indirect
  //reference from leafRef

  leafRef = null;
  //#NOW #tree can be garbage collected

#leaf handhaaft een verwijzing naar zijn ouder ( parentNode ) en recursief tot #tree , dus alleen wanneer leafRef wordt vernietigd, is de hele boom onder #tree een kandidaat voor GC.

DOM -substrees