Maak kennis met de Geheugeninspecteur

Kim-Anh Tran
Kim-Anh Tran

Dit artikel introduceert de Memory Inspector die in Chrome 91 is geland. Hiermee kunt u uw ArrayBuffer-, TypedArray-, DataView- en Wasm-geheugen inspecteren.

Invoering

Heeft u ooit zin willen geven aan de gegevens in uw ArrayBuffer? Vóór de Memory Inspector bood DevTools slechts beperkt inzicht in ArrayBuffers. De inspectie vanuit de Scope- weergave tijdens een foutopsporingssessie was beperkt tot het bekijken van een lijst met afzonderlijke waarden binnen de arraybuffer, waardoor het moeilijk werd om de gegevens als geheel te begrijpen. Als voorbeeld toont de Scope- weergave de buffer als uitbreidbare reeksen arrays in het onderstaande voorbeeld:

Bereikweergave in DevTools

Navigeren naar een bepaald bereik binnen de buffer was een pijnpunt, waarbij de gebruiker naar beneden moest scrollen om uiteindelijk bij die index te komen. Maar zelfs als het navigeren naar een positie gemakkelijk zou zijn, is deze manier om waarden daadwerkelijk te inspecteren omslachtig: het is moeilijk te zeggen wat deze cijfers betekenen. En vooral: wat als ze niet als enkele bytes moeten worden geïnterpreteerd, maar bijvoorbeeld als 32-bits gehele getallen?

Waarden inspecteren met behulp van de Memory Inspector

Geheugeninspecteur

Met Chrome 91 introduceren we de Memory Inspector, een hulpmiddel om arraybuffers te inspecteren. Misschien heb je eerder geheugeninspectietools gezien om binaire gegevens te bekijken, die de binaire inhoud samen met hun adressen in een raster weergeven, en die verschillende manieren bieden om de onderliggende waarden te interpreteren. Dit is wat de Memory Inspector u biedt. Met de Memory Inspector kunt u nu de inhoud bekijken, er doorheen navigeren en typen selecteren die u wilt gebruiken om de betreffende waarden te interpreteren. Het toont de ASCII-waarden direct naast de bytes en stelt de gebruiker in staat verschillende endianness te selecteren. Zie hieronder de Memory Inspector in actie:

Wil je het uitproberen? Voor meer informatie over het openen van Memory Inspector en het bekijken van uw arraybuffer (of TypedArray, DataView of Wasm Memory) en voor meer informatie over het gebruik ervan, gaat u naar onze documentatie over Memory Inspector . Probeer het eens met deze speelgoedvoorbeelden (voor JS, Wasm en C++).

Het ontwerpen van de Geheugeninspecteur

In dit deel zullen we bekijken hoe de Memory Inspector is ontworpen met behulp van Web Components, en we zullen een van de ontwerpdoelen laten zien die we hadden en hoe we deze hebben geïmplementeerd. Als je nieuwsgierig bent en meer wilt zien, bekijk dan ons ontwerpdocument voor de Memory Inspector.

Je hebt misschien onze blogpost over Migreren naar Web Components gezien, waarin Jack onze interne handleiding heeft gepubliceerd over het bouwen van UI-componenten met behulp van Web Components. De migratie naar Web Components viel samen met ons werk aan de Memory Inspector, en als gevolg daarvan besloten we het nieuwe systeem eens te proberen. Hieronder ziet u een diagram met de componenten die we hebben gebouwd om de Memory Inspector te maken (merk op dat we dit intern Linear Memory Inspector noemen):

Webcomponenten

De component LinearMemoryInspector is de bovenliggende component die de subcomponenten combineert die alle elementen in de Memory Inspector vormen. Er zijn in principe een Uint8Array en een address voor nodig, en bij elke wijziging van een van beide worden de gegevens doorgegeven aan de onderliggende bestanden, wat een nieuwe weergave teweegbrengt. De LinearMemoryInspector zelf geeft drie subcomponenten weer:

  1. LinearMemoryViewer (toont de waarden),
  2. LinearMemoryNavigator (waardoor de navigatie mogelijk is), en
  3. LinearMemoryValueInterpreter (toont verschillende typen interpretaties van de onderliggende gegevens).

De laatste is zelf een bovenliggende component, die de ValueInterpreterDisplay (waarin de waarden worden weergegeven) en de ValueInterpreterSettings (waarmee wordt geselecteerd welke typen op de display worden weergegeven) weergeeft.

Elk van de componenten is ontworpen om slechts één klein onderdeel van de gebruikersinterface te vertegenwoordigen, zodat componenten indien nodig opnieuw kunnen worden gebruikt. Telkens wanneer nieuwe gegevens op een component worden ingesteld, wordt een nieuwe weergave geactiveerd, waarbij de gereflecteerde verandering wordt weergegeven op de gegevens die op de component zijn ingesteld. Hieronder ziet u een voorbeeld van een workflow met onze componenten, waarbij de gebruiker het adres in de adresbalk wijzigt, wat een update activeert door de nieuwe gegevens in te stellen, in dit geval het adres dat moet worden bekeken:

Componentendiagram

De LinearMemoryInspector voegt zichzelf toe als luisteraar aan de LinearMemoryNavigator . De functie addressChanged moet worden geactiveerd bij een gebeurtenis address-changed . Zodra de gebruiker nu de adresinvoer aan het bewerken is, wordt de bovengenoemde gebeurtenis verzonden, zodat de functie addressChanged wordt aangeroepen. Deze functie slaat het adres nu intern op en werkt de subcomponenten ervan bij met behulp van de data(address, ..) -setter. De subcomponenten slaan het adres intern op en geven hun weergaven opnieuw weer, waarbij de inhoud op dat specifieke adres wordt weergegeven.

Ontwerpdoel: prestaties en geheugenverbruik onafhankelijk maken van de buffergrootte

Eén aspect dat we tijdens het ontwerp van de Memory Inspector in gedachten hadden, was dat de prestaties van de Memory Inspector onafhankelijk moesten zijn van de buffergrootte.

Zoals je in het vorige deel hebt gezien, gebruikt de component LinearMemoryInspector een UInt8Array om de waarden weer te geven. Tegelijkertijd wilden we er zeker van zijn dat de Memory Inspector niet de hele gegevens hoefde bij te houden, omdat de Memory Inspector slechts een deel ervan laat zien (wasm-geheugen kan bijvoorbeeld zo groot zijn als 4 GB, en we willen niet dat om 4 GB op te slaan in de Memory Inspector).

Om er dus voor te zorgen dat de snelheid en het geheugenverbruik van de Memory Inspector onafhankelijk zijn van de daadwerkelijke buffer die we laten zien, laten we de LinearMemoryInspector -component slechts een subbereik van de oorspronkelijke buffer behouden.

Om dit te laten werken, moet de LinearMemoryInspector eerst nog twee argumenten gebruiken: een memoryOffset en een outerMemoryLength . De memoryOffset geeft de offset aan, waarop de doorgegeven Uint8Array begint, en is nodig om de juiste dataadressen weer te geven. De outerMemoryLength is de lengte van de oorspronkelijke buffer en is vereist om te begrijpen welk bereik we kunnen weergeven:

buffer

Met deze informatie kunnen we ervoor zorgen dat we nog steeds dezelfde weergave kunnen weergeven als voorheen (de inhoud rond het address ), zonder dat we daadwerkelijk over alle gegevens beschikken. Dus wat moet u doen als er om een ​​ander adres wordt gevraagd dat in een ander bereik valt? In dat geval activeert de LinearMemoryInspector een RequestMemoryEvent , die het huidige bereik bijwerkt dat wordt bewaard; hieronder ziet u een voorbeeld:

Stroomdiagram van gebeurtenistrigger

In dit voorbeeld navigeert de gebruiker door de geheugenpagina (de Memory Inspector gebruikt paging om stukjes gegevens weer te geven), waardoor een PageNavigationEvent wordt geactiveerd, die op zijn beurt een RequestMemoryEvent activeert. Die gebeurtenis start het ophalen van het nieuwe bereik, dat vervolgens wordt doorgegeven aan de LinearMemoryInspector component door het instellen van de gegevens. Als gevolg hiervan tonen we de nieuw opgehaalde gegevens.

Oja, en wist je dat? U kunt zelfs het geheugen inspecteren in Wasm- en C/C++-code

De Memory Inspector is niet alleen beschikbaar voor ArrayBuffers in JavaScript, maar kan ook worden gebruikt voor het inspecteren van Wasm-geheugen en geheugen waarnaar wordt verwezen door C/C++-referenties/pointers (met behulp van onze DWARF-extensie - probeer het eens als je dat nog niet hebt gedaan! Zie hier Debuggen van WebAssembly met moderne tools . Een kleine blik op de Memory Inspector in actie voor het native debuggen van C++ op internet:

Inspecteer het geheugen in C++

Conclusie

Dit artikel presenteerde de Memory Inspector en liet een glimp zien van het ontwerp ervan. We hopen dat de Memory Inspector u zal helpen begrijpen wat er in uw ArrayBuffer gebeurt :-). Als je suggesties hebt om het te verbeteren, laat het ons weten en dien een bug in !

Download de voorbeeldkanalen

Overweeg om Chrome Canary , Dev of Beta te gebruiken als uw standaard ontwikkelingsbrowser. Met deze voorbeeldkanalen krijgt u toegang tot de nieuwste DevTools-functies, kunt u geavanceerde webplatform-API's testen en kunt u problemen op uw site opsporen voordat uw gebruikers dat doen!

Neem contact op met het Chrome DevTools-team

Gebruik de volgende opties om de nieuwe functies, updates of iets anders gerelateerd aan DevTools te bespreken.