Introduzione a Memory Inspector

Kim-Anh Tran
Kim-Anh Tran

Questo articolo introduce il controllo della memoria disponibile in Chrome 91. Consente di ispezionare ArrayBuffer, TypedArray, DataView e la memoria Wasm.

Introduzione

Hai mai voluto dare un senso ai dati in ArrayBuffer? Prima di Memory Inspector, DevTools consentiva solo insight limitati su ArrayBuffers. L'ispezione dalla visualizzazione Ambito durante una sessione di debug era limitata alla visualizzazione di un elenco di singoli valori nel buffer dell'array, il che rendeva difficile dare un senso ai dati nel complesso. Ad esempio, la visualizzazione Ambito mostra il buffer come intervalli espandibili di array nell'esempio riportato di seguito:

Visualizzazione ambito in DevTools

L'accesso a un determinato intervallo all'interno del buffer era un problema, richiedendo all'utente di scorrere verso il basso per accedere all'indice. Ma anche se raggiungere una posizione sarebbe facile, questo modo di inspecting effettivamente i valori è complicato: è difficile dire il significato di questi numeri. In particolare, cosa succede se non dovrebbero essere interpretati come byte singoli, ma ad esempio come numeri interi a 32 bit?

Ispezione dei valori con Controllo memoria

Controllo memoria

Con Chrome 91 stiamo introducendo Memory Inspector, uno strumento per esaminare i buffer degli array. Probabilmente hai già visto gli strumenti di ispezione della memoria per visualizzare i dati binari, che mostrano i contenuti binari in una griglia insieme ai relativi indirizzi e offrono diversi modi di interpretare i valori sottostanti. Ecco cosa ti offre la funzionalità Controllo memoria. Con Controllo memoria, ora puoi visualizzare i contenuti, esplorarli e selezionare i tipi da utilizzare per interpretare i valori in questione. Mostra i valori ASCII direttamente accanto ai byte e consente all'utente di selezionare un livello di endpoint diverso. Guarda come funziona la funzionalità Controllo memoria:

Vuoi provare? Per informazioni su come aprire Memory Inspector e visualizzare il buffer di array (o TypedArray, DataView o Wasm Memory) e ulteriori informazioni su come utilizzarlo, consulta la nostra documentazione relativa a Memory Inspector. Prova questi esempi di giocattoli (per JS, Wasm e C++).

Progettazione di Memory Inspector

In questa parte, vedremo come viene progettato Memory Inspector utilizzando i componenti web, nonché uno degli obiettivi di progettazione che ci siamo prefissati e il modo in cui l'abbiamo implementato. Se sei curioso e vuoi saperne di più, dai un'occhiata al nostro documento sul design per l'ispettore memoria.

Potresti aver visto il nostro post del blog sulla migrazione ai componenti web, in cui Jack ha pubblicato la nostra guida interna su come creare componenti dell'interfaccia utente utilizzando Web Componenti. La migrazione a Web Componenti ha coinciso con il nostro lavoro su Memory Inspector e, di conseguenza, abbiamo deciso di provare il nuovo sistema. Di seguito è riportato un diagramma che mostra i componenti che abbiamo creato per creare Memory Inspector (tieni presente che internamente lo chiamiamo Controllo memoria lineare):

Componenti web

Il componente LinearMemoryInspector è il componente principale che combina i componenti secondari che costituiscono tutti gli elementi di Controllo memoria. In pratica sono necessari un Uint8Array e un address e a ogni modifica i dati vengono propagati alle unità secondarie, attivando una nuova visualizzazione. LinearMemoryInspector esegue il rendering di tre sottocomponenti:

  1. LinearMemoryViewer (mostra i valori),
  2. LinearMemoryNavigator (consente la navigazione) e
  3. LinearMemoryValueInterpreter (mostra diverse interpretazioni dei tipi di dati sottostanti).

Quest'ultimo è a sua volta un componente principale che esegue il rendering di ValueInterpreterDisplay (mostrando i valori) e di ValueInterpreterSettings (selezionando i tipi da visualizzare nella visualizzazione).

Ciascuno dei componenti è progettato per rappresentare un solo piccolo componente dell'interfaccia utente, in modo che i componenti possano essere riutilizzati, se necessario. Ogni volta che vengono impostati nuovi dati su un componente, viene attivato un nuovo rendering, che mostra la modifica riflessa sui dati impostati nel componente. Di seguito è riportato un esempio di flusso di lavoro con i nostri componenti, in cui l'utente modifica l'indirizzo nella barra degli indirizzi e questo attiva un aggiornamento impostando i nuovi dati, in questo caso l'indirizzo da visualizzare:

Diagramma dei componenti

LinearMemoryInspector si aggiunge come listener su LinearMemoryNavigator. La funzione addressChanged deve essere attivata su un evento address-changed. Non appena l'utente modifica l'input dell'indirizzo, viene inviato l'evento sopra indicato, in modo che venga richiamata la funzione addressChanged. Questa funzione ora salva l'indirizzo internamente e aggiorna i relativi componenti secondari utilizzando un setter data(address, ..). I sottocomponenti salvano l'indirizzo internamente e mostrano nuovamente le proprie visualizzazioni, mostrando i contenuti a quell'indirizzo.

Obiettivo di progettazione: rendere le prestazioni e il consumo della memoria indipendenti dalla dimensione del buffer

Un aspetto che abbiamo pensato durante la progettazione di Memory Inspector era che le sue prestazioni fossero indipendenti dalla dimensione del buffer.

Come hai visto nella parte precedente, il componente LinearMemoryInspector richiede un UInt8Array per eseguire il rendering dei valori. Allo stesso tempo volevamo assicurarci che Memory Inspector non dovesse mantenere tutti i dati, poiché Memory Inspector ne mostra solo una parte (ad esempio, la memoria Wasm può avere dimensioni fino a 4 GB e non vogliamo memorizzarne 4 GB all'interno di Memory Inspector).

Quindi, per garantire che la velocità e il consumo di memoria di Memory Inspector siano indipendenti dal buffer effettivo visualizzato, lascia che il componente LinearMemoryInspector mantenga solo una sottointervallo del buffer originale.

Affinché questo comando funzioni, LinearMemoryInspector deve prima accettare altri due argomenti: memoryOffset e outerMemoryLength. memoryOffset indica l'offset, in cui inizia l'Uint8Array passato, ed è necessario per visualizzare gli indirizzi dati corretti. outerMemoryLength è la lunghezza del buffer originale ed è necessario per capire quale intervallo possiamo mostrare:

buffer

Con queste informazioni possiamo garantire la stessa visualizzazione di prima (i contenuti intorno a address), senza disporre effettivamente di tutti i dati. Quindi cosa fare se viene richiesto un indirizzo diverso, che rientra in un intervallo diverso? In questo caso, LinearMemoryInspector attiva un RequestMemoryEvent, che aggiorna l'intervallo attuale che viene mantenuto. Di seguito è riportato un esempio:

Diagramma di flusso del trigger di eventi

In questo esempio, l'utente naviga nella pagina della memoria (il Controllo memoria utilizza il paging per mostrare blocchi di dati), attivando un PageNavigationEvent, che a sua volta attiva un RequestMemoryEvent. Questo evento avvia il recupero del nuovo intervallo, che viene poi propagato al componente LinearMemoryInspector attraverso l'impostazione dei dati. Di conseguenza, mostriamo i dati appena recuperati.

Ah, e lo sapevi? Puoi persino ispezionare la memoria nel codice Wasm e C/C++

Memory Inspector non è disponibile solo per ArrayBuffers in JavaScript, ma può essere utilizzato anche per ispezionare la memoria e la memoria Wasm a cui puntano riferimenti/punter C/C++ (usando la nostra estensione DWARF, prova se non l'hai ancora fatto). Vedi Eseguire il debug di WebAssembly con strumenti moderni qui. Ecco una breve panoramica di Memory Inspector in azione per il debug nativo di C++ sul web:

Ispeziona la memoria in C++

Conclusione

Questo articolo presentava l'ispezione della memoria e ne mostrava il design. Ci auguriamo che Memory Inspector ti aiuti a capire cosa sta succedendo in ArrayBuffer :-). Se hai suggerimenti per migliorarlo, contattaci e segnala un bug.

Scarica i canali in anteprima

Prendi in considerazione l'utilizzo di Chrome Canary, Dev o beta come browser di sviluppo predefinito. Questi canali in anteprima ti consentono di accedere alle funzionalità di DevTools più recenti, di testare le API per piattaforme web all'avanguardia e di individuare eventuali problemi sul tuo sito prima che lo facciano gli utenti.

Contattare il team di Chrome DevTools

Utilizza le opzioni seguenti per discutere delle nuove funzionalità e delle modifiche nel post o di qualsiasi altra cosa relativa a DevTools.

  • Inviaci un suggerimento o un feedback tramite crbug.com.
  • Segnala un problema DevTools utilizzando Altre opzioni   Altre   > Guida > Segnala i problemi di DevTools in DevTools.
  • Tweet all'indirizzo @ChromeDevTools.
  • Lascia commenti sui video di YouTube o sui suggerimenti di DevTools in DevTools Video di YouTube.