Memory Inspector のご紹介

Kim-Anh Tran
Kim-Anh Tran

この記事では、Chrome 91 に導入されたメモリ インスペクタについて説明します。これにより、ArrayBuffer、TypedArray、DataView、Wasm メモリを検査できます。

はじめに

ArrayBuffer 内のデータを理解したいと思ったことはありませんか?Memory Inspector が登場する前は、DevTools で ArrayBuffer に関する分析情報を確認できるのは限られていました。デバッグ セッション中の [スコープ] ビューからの検査は、配列バッファ内の単一値のリストの表示に限定されていたため、データ全体を把握することが困難でした。たとえば、次の例の [スコープ] ビューでは、バッファが配列の展開可能な範囲として表示されます。

DevTools のスコープビュー

バッファ内の特定の範囲に移動するのは手間がかかり、ユーザーは最終的にそのインデックスに到達するために下にスクロールする必要がありました。ただし、位置に移動するのは簡単でも、値を実際に検査する方法は煩雑です。これらの数値の意味を判断するのは困難です。特に、単一バイトではなく、32 ビット整数として解釈する必要がある場合はどうすればよいですか?

Memory Inspector を使用して値を検査する

Memory Inspector

Chrome 91 では、配列バッファを検査するツールである Memory Inspector を導入します。バイナリ データを表示するメモリ検査ツールは、バイナリ コンテンツをアドレスとともにグリッドに表示し、基盤となる値をさまざまな方法で解釈できるようにします。これが Memory Inspector が提供する機能です。Memory Inspector を使用すると、コンテンツを表示、移動し、手元の値の解釈に使用する型を選択できます。ASCII 値がバイトのすぐ横に表示され、ユーザーは異なるエンディアンを選択できます。Memory Inspector の動作は次のとおりです。

お試しになる場合は、Memory Inspector を開いて配列バッファ(または TypedArray、DataView、Wasm Memory)を表示する方法と、その使用方法の詳細については、Memory Inspector に関するドキュメントをご覧ください。これらのサンプル(JS、Wasm、C++ 用)をお試しください。

Memory Inspector の設計

このパートでは、Web コンポーネントを使用してメモリ インスペクタがどのように設計されているかを確認し、設計目標の 1 つとその実装方法について説明します。詳しくは、Memory Inspector の設計ドキュメントをご覧ください。

ウェブ コンポーネントへの移行に関するブログ投稿をご覧になったことがあるかもしれません。この投稿では、Jack がウェブ コンポーネントを使用して UI コンポーネントを作成する方法に関する社内ガイドを公開しています。ウェブ コンポーネントへの移行はメモリ インスペクタの作業と重なっていたため、新しいシステムを試すことにしました。以下は、Memory Inspector の作成に使用したコンポーネントを示した図です(社内では Linear Memory Inspector と呼んでいます)。

ウェブ コンポーネント

LinearMemoryInspector コンポーネントは、Memory Inspector 内のすべての要素を構築するサブコンポーネントを組み合わせた親コンポーネントです。基本的には Uint8Arrayaddress を受け取り、どちらかが変更されるたびにデータを子に伝播し、再レンダリングをトリガーします。LinearMemoryInspector 自体は、次の 3 つのサブコンポーネントをレンダリングします。

  1. LinearMemoryViewer(値を表示)、
  2. LinearMemoryNavigator(ナビゲーションを許可)
  3. LinearMemoryValueInterpreter(基盤となるデータの異なるタイプの解釈を示す)。

後者は親コンポーネントであり、ValueInterpreterDisplay(値を表示)と ValueInterpreterSettings(ディスプレイに表示するタイプを選択)をレンダリングします。

各コンポーネントは、必要に応じてコンポーネントを再利用できるように、UI の 1 つの小さなコンポーネントのみを表すように設計されています。コンポーネントに新しいデータが設定されると、再レンダリングがトリガーされ、コンポーネントに設定されたデータに反映された変更が表示されます。以下の例は、コンポーネントを使用したワークフローの一例です。ユーザーがアドレスバーで住所を変更すると、新しいデータ(この場合は表示する住所)が設定され、更新がトリガーされます。

コンポーネントの図

LinearMemoryInspector は、LinearMemoryNavigator のリスナーとして自身を追加します。addressChanged 関数は、address-changed イベントでトリガーされます。ユーザーが住所入力を編集するとすぐに、前述のイベントが送信され、addressChanged 関数が呼び出されます。この関数は、アドレスを内部に保存し、data(address, ..) セッターを使用してサブコンポーネントを更新するようになりました。サブコンポーネントは住所を内部に保存し、ビューを再レンダリングして、その特定の住所のコンテンツを表示します。

設計目標: パフォーマンスとメモリ消費をバッファサイズから独立させる

Memory Inspector の設計時に考慮した点の 1 つは、Memory Inspector のパフォーマンスがバッファサイズに依存しないようにすることです。

前のセクションで説明したように、LinearMemoryInspector コンポーネントは UInt8Array を受け取って値をレンダリングします。同時に、Memory Inspector はデータの一部のみを表示するため、Memory Inspector がデータ全体を保持する必要がないようにしました(例: Wasm メモリは最大 4 GB になる可能性がありますが、Memory Inspector 内に 4 GB を保存することはできません)。

そのため、Memory Inspector の速度とメモリ使用量が表示される実際のバッファから独立するように、LinearMemoryInspector コンポーネントは元のバッファのサブ範囲のみを保持します。

これを機能させるには、まず LinearMemoryInspectormemoryOffsetouterMemoryLength の 2 つの引数を渡す必要があります。memoryOffset は、渡された Uint8Array が開始するオフセットを示します。正しいデータアドレスをレンダリングするために必要です。outerMemoryLength は元のバッファの長さで、表示できる範囲を把握するために必要です。

buffer

この情報があれば、すべてのデータを実際に配置しなくても、以前と同じビュー(address の周囲のコンテンツ)をレンダリングできます。別の住所がリクエストされ、別の範囲に該当する場合はどうすればよいですか?その場合、LinearMemoryInspectorRequestMemoryEvent をトリガーし、保持されている現在の範囲を更新します。例を次に示します。

イベント トリガーのフロー図

この例では、ユーザーがメモリページに移動します(Memory Inspector はページングを使用してデータのチャンクを表示しています)。これにより PageNavigationEvent がトリガーされ、RequestMemoryEvent がトリガーされます。このイベントにより、新しい範囲の取得が開始され、データの設定を通じて LinearMemoryInspector コンポーネントに伝播されます。その結果、新しく取得したデータが表示されます。

ご存じですか?Wasm コードと C/C++ コードのメモリを検査することもできます。

Memory Inspector は、JavaScript の ArrayBuffers で使用できるだけでなく、Wasm メモリや C/C++ 参照/ポインタによって参照されるメモリの検査にも使用できます(DWARF 拡張機能を使用してください。まだお試しでない場合は、ぜひお試しください。最新のツールで WebAssembly をデバッグするをご覧ください。ウェブ上の C++ のネイティブ デバッグで Memory Inspector がどのように機能するか、簡単に説明します。

C++ でメモリを検査する

まとめ

この記事では、メモリ インスペクタとその設計について説明しました。Memory Inspector が ArrayBuffer で何が起こっているかを把握するうえで役立つことを願っております。改善の提案がある場合は、バグを報告してください。

プレビュー チャネルをダウンロードする

デフォルトの開発用ブラウザとして Chrome の CanaryDevBeta のいずれかを使用することを検討してください。これらのプレビュー チャンネルでは、最新の DevTools 機能にアクセスしたり、最先端のウェブ プラットフォーム API をテストしたりできます。また、ユーザーよりも先にサイトの問題を見つけることもできます。

Chrome DevTools チームに問い合わせる

次のオプションを使用して、DevTools の新機能、アップデート、その他のトピックについて話し合います。