記憶體檢查器簡介

Kim-Anh Tran
Kim-Anh Tran

本文將介紹已在 Chrome 91 中推出的記憶體檢查器。可讓您檢查 ArrayBuffer、TypedArray、DataView 和 Wasm 記憶體。

簡介

您是否曾想瞭解 ArrayBuffer 中的資料?在記憶體檢查器推出前,開發人員工具只能針對 ArrayBuffer 提供有限的洞察資料。在偵錯工作階段中,Scope 檢視畫面只能檢視陣列緩衝區中的單一值清單,因此很難解讀資料。舉例來說,在下方範例中,Scope 檢視畫面會將緩衝區顯示為可展開的陣列範圍:

開發人員工具中的範圍檢視畫面

在緩衝區內導覽至特定範圍是個痛點,因為使用者必須向下捲動才能找到該索引。不過,即使前往某個位置很容易,但實際上檢查值的方式很麻煩:很難判斷這些數字的含義。特別是,如果不應解讀為單一位元組,而是 32 位元整數,該怎麼辦?

使用記憶體檢查器檢查值

記憶體檢查工具

我們在 Chrome 91 中推出了記憶體檢查器,這是用來檢查陣列緩衝區的工具。您可能曾經使用記憶體檢查工具查看二進位資料,這類工具會以格狀方式顯示二進位內容和其位址,並提供不同的方式解讀基礎值。這就是記憶體檢查器提供的功能。有了記憶體檢視器,您現在可以查看內容、瀏覽內容,以及選取用於解讀當前值的類型。它會直接在位元組旁邊顯示 ASCII 值,並允許使用者選取不同的字節順序。請參閱下方記憶體檢查工具的實際運作情形:

想試試看嗎?如要瞭解如何開啟記憶體檢查器,以及查看陣列緩衝區 (或 TypedArray、DataView 或 Wasm 記憶體) 和如何使用記憶體檢查器的更多資訊,請參閱記憶體檢查器說明文件。請試試這些玩具範例 (適用於 JS、Wasm 和 C++)。

設計記憶體檢查工具

在本節中,我們將瞭解如何使用 Web 元件設計記憶體檢查器,並說明我們設定的其中一個設計目標,以及如何實作。如想進一步瞭解,請參閱記憶體檢查器的設計文件

您可能看過我們關於遷移至 Web 元件的網誌文章,Jack 在其中發布了我們的內部指南,說明如何使用 Web 元件建構 UI 元件。遷移至 Web 元件恰好與我們在記憶體檢查器上的工作重疊,因此我們決定試試新系統。下圖顯示我們建構的元件,用於建立記憶體檢查器 (請注意,我們在內部稱之為「線性記憶體檢查器」):

網頁元件

LinearMemoryInspector 元件是父項元件,可結合子元件,在記憶體檢查器中建立所有元素。它基本上會採用 Uint8Arrayaddress,並在每次變更時將資料傳播至子項,進而觸發重新算繪。LinearMemoryInspector 本身會轉譯三個子元件:

  1. LinearMemoryViewer (顯示值),
  2. LinearMemoryNavigator (允許導覽) 和
  3. LinearMemoryValueInterpreter (顯示基礎資料的不同類型解讀方式)。

後者本身是父項元件,會算繪 ValueInterpreterDisplay (顯示值) 和 ValueInterpreterSettings (選取在顯示畫面中顯示的類型)。

每個元件都只代表 UI 的一小部分,以便在需要時重複使用。每當在元件上設定新資料時,系統就會觸發重新算繪作業,顯示在元件上設定的資料所反映的變更。以下是使用元件的流程工作範例,使用者在網址列中變更地址,系統會設定新資料 (在本例中為要查看的地址) 來觸發更新:

元件圖表

LinearMemoryInspector 會將自身新增為 LinearMemoryNavigator 的事件監聽器。addressChanged 函式會在 address-changed 事件上觸發。只要使用者編輯地址輸入內容,系統就會傳送上述事件,例如呼叫 addressChanged 函式。這個函式現在會在內部儲存地址,並使用 data(address, ..) Setter 更新其子元件。子元件會將位址儲存在內部,並重新轉譯其檢視畫面,顯示該特定位址的內容。

設計目標:讓效能和記憶體用量不受緩衝區大小影響

在設計記憶體檢查工具時,我們考量到一個重點,就是記憶體檢查工具的效能不應受緩衝區大小影響。

如您在前一個部分所見,LinearMemoryInspector 元件會使用 UInt8Array 算繪值。同時,我們也想確保記憶體檢查器不需要保留整個資料,因為記憶體檢查器只會顯示部分資料 (例如,Wasm 記憶體可能會達到 4GB,而我們不想在記憶體檢查器中儲存 4GB)。

因此,為確保記憶體檢查器的速度和記憶體用量不受我們顯示的實際緩衝區影響,我們讓 LinearMemoryInspector 元件只保留原始緩衝區的子範圍

如要讓這項功能運作,LinearMemoryInspector 首先需要再使用兩個引數:memoryOffsetouterMemoryLengthmemoryOffset 會指出偏移量,即傳遞的 Uint8Array 開始的位置,必須顯示正確的資料位址。outerMemoryLength 是原始緩衝區的長度,必須瞭解我們可以顯示的範圍:

緩衝區

有了這些資訊,我們就能確保在沒有所有資料的情況下,仍能呈現與先前相同的檢視畫面 (address 周圍的內容)。如果要求的地址屬於其他範圍,該怎麼辦?在這種情況下,LinearMemoryInspector 會觸發 RequestMemoryEvent,以更新目前保留的範圍;以下為範例:

事件觸發條件流程圖

在這個範例中,使用者瀏覽記憶體頁面 (記憶體檢查器會使用分頁功能顯示資料區塊),進而觸發 PageNavigationEvent,而 PageNavigationEvent 本身會觸發 RequestMemoryEvent。該事件會啟動擷取新範圍的程序,然後透過設定資料,將範圍傳播至 LinearMemoryInspector 元件。因此,我們會顯示新擷取的資料。

另外,你知道嗎?您甚至可以檢查 Wasm 和 C/C++ 程式碼中的記憶體

記憶體檢查器不僅可用於 JavaScript 中的 ArrayBuffers,還可用於檢查 Wasm 記憶體,以及 C/C++ 參照/指標所指向的記憶體 (使用 DWARF 擴充功能 - 如未使用過,請試試看!請參閱「使用新式工具對 WebAssembly 進行偵錯」一文。以下是記憶體檢查器在網路上進行 C++ 原生偵錯時的運作情形:

在 C++ 中檢查記憶體

結論

本文介紹了記憶體檢查器,並簡要說明其設計。我們希望記憶體檢查器能協助您瞭解 ArrayBuffer 中的情況 :-)。如果您有改善建議,歡迎與我們分享,並回報錯誤

下載預覽管道

建議您將 Chrome Canary開發人員版Beta 版設為預設開發人員版瀏覽器。這些預覽管道可讓您存取最新的 DevTools 功能,測試最新的網路平台 API,並在使用者發現問題前,協助您找出網站的問題!

與 Chrome 開發人員工具團隊聯絡

請使用下列選項討論新功能、更新或任何與開發人員工具相關的內容。