高レベルのアプリケーションでのメモリ使用量

このトピックでは、上位レベルのアプリケーションでのメモリ使用量の詳細について説明します。 リアルタイム対応アプリケーション (RTApps) で使用できるメモリの詳細については、「 メモリと待機時間の考慮事項を管理 する」を参照してください。

高レベルのアプリケーションでは、次のメモリとストレージにアクセスできます。

  • 高レベルのコア上の 256 KiB RAM。高レベルのアプリケーション用に完全に予約されています。 この領域の最大 1 KiB は、上位レベルのアプリケーションと RTApps が通信する共有バッファー チャネルごとに割り当てられます。
  • 1 MiB 読み取り専用フラッシュ メモリ。高レベルコアとリアルタイム コア間で共有されます。
  • 読み取り/書き込み (変更可能) ストレージ。これは、デバイスの再起動時に保持されます。 変更可能なストレージの詳細については、「 Azure Sphere でのストレージの使用」を参照してください。

メモ

フラッシュを繰り返し更新すると、最終的にフラッシュが摩耗し、無効になります。 そのため、フラッシュの不要な更新を避けるためにコードを設計する必要があります。 たとえば、再起動後に保存された状態を回復できるように、終了する前にアプリケーションの状態を保存する場合は、状態が変更された場合にのみ、アプリケーションの状態をフラッシュに保存することを検討してください。

フラッシュ メモリの使用量を決定する

フラッシュ メモリの使用状況を判断するには、イメージ メタデータ、アプリケーション マニフェスト、実行可能イメージを含むイメージ パッケージ ファイルのサイズのみを考慮してください。 Azure Sphere OS や、周辺機器を制御し、Azure IoT Hubへの接続を有効にするランタイム サービスや共有ライブラリなど、Microsoft が提供するコンポーネントで必要なストレージを考慮する必要はありません。 同様に、アプリケーションの完全バックアップ コピーのサイズや、フェールオーバーまたはロールバックを有効にするコンポーネントのサイズを含める必要はありません。また、オーバーエア更新プログラムの破損や問題が発生した場合に備えて、フェールオーバーまたはロールバックを有効にするコンポーネントも含める必要はありません。

ただし、開発とデバッグ中に、デバッガーのサイズは制限に対してカウントされます。 デバッガーは az sphere device enable-development によって自動的に追加され、[az sphere device enable-cloud-test](.. によって削除されます。/reference/az sphere-device.md)。 Microsoft Azure Sphere SDK インストール ディレクトリの DebugTools フォルダーで gdbserver.imagepackage を検索することで、SDK で使用されるデバッガーのサイズを確認できます。

アプリケーション イメージ パッケージとデバッガー (存在する場合) が 1 MiB の合計制限を超えた場合、 az sphere device sideload コマンドはエラーを返します。 azure Sphere カタログに新しいイメージをアップロードする az sphere image add --image コマンドも、イメージ パッケージが 1 MiB を超えた場合にエラーを返します。

256 KiB RAM の制限は、アプリケーションだけに適用されます。デバッガーで使用される RAM を許可する必要はありません。 追加のメモリは、カーネル割り当て用に予約されています。

現在の Azure Sphere チップ (MT3620) 用に書き込まれたアプリケーションでは、使用可能なフラッシュと RAM が増える可能性があります (ただし、減少することはありません)。 今後の Azure Sphere チップの制限は異なる場合があります。

メモリ不足状態

アプリケーションで RAM が多すぎる場合、Azure Sphere OS は SIGKILL シグナルで終了します。 たとえば、デバッガーには次の情報が表示されます。

Child terminated with signal = 0x9 (SIGKILL)

SIGKILL シグナルは、高レベルのアプリケーションが SIGTERM 要求を受け取った後に終了に失敗した場合にも発生します。 詳細については、「 アプリケーションのライフサイクル 」を参照してください。

メモリ不足状態によるアプリケーションのクラッシュを回避するには、 上位レベルのアプリケーションで RAM 使用率を管理するためのベスト プラクティスに関するページを参照してください。

ランタイム アプリケーションの RAM 使用率を決定する

Azure Sphere には、実行時にメモリ使用量情報を取得するためのいくつかの関数が用意されています。 これらを使用すると、高レベルのアプリケーションのメモリ使用量を監視できます。これにより、メモリ使用量が 256 KiB 制限内で指定したしきい値を超えた場合に、アプリケーションを安全に再起動できます。 使用可能な関数は次のとおりです。

  • Applications_GetTotalMemoryUsageInKB: メモリ使用量の合計を kibibytes で取得します。 これは、アプリまたはデバッグ サーバーに代わってカーネル割り当て (ソケットのバッファーなど) を含む、システム上のアプリの物理メモリ使用量の合計であり、(KiB では) 生の値として返されます。
  • Applications_GetUserModeMemoryUsageInKB: ユーザー モードのメモリ使用量を kibibytes で取得します。 これは、アプリによって直接使用される物理メモリの量、その代わりに任意のライブラリで使用されるメモリ ( アノン 割り当てとも呼ばれます)、デバッグ サーバーによって使用されるメモリ (KiB では) の生の値として返されます。
  • Applications_GetPeakUserModeMemoryUsageInKB: ユーザー モードのメモリ使用量のピークを kibibytes で取得します。 これは、現在のセッションで使用されるユーザー メモリの最大量です。 アプリケーションのメモリ使用量をテストするときは、この値が 256 KiB を超えないようにする必要があります。 この値は、アプリが再起動または再デプロイされるたびにリセットされます。 この関数を使用して、アプリケーションが推奨される 256 KiB の制限にどの程度近づいているかをおおよそ確認します。

これらの関数を高度なアプリケーションで使用するには、applications.h ヘッダー ファイルを含めます。 開発中にこれらの関数を使用して、アプリケーションの全体的なメモリ使用量を把握できますが、ログと共に使用 して、フィールド内のデバイスから情報をキャプチャすることもできます。 メモリの過剰使用検出とクリーンアップ スニペットは、予期しないメモリ使用量を検出して適切に処理する方法を示しています。

メモ

これらの関数は、OS から見たメモリ使用量を返します。 現時点では、ユーザー ヒープ上の割り当てに対するアプリケーションによるメモリの解放は、これらの関数では報告されません。 メモリは今後使用するために malloc ライブラリに返されますが、OS 自体によってメモリが割り当てられ解放されない限り、OS によって報告される統計情報は変更されません。 たとえば、ソケットのメモリを割り当てる場合があります。 したがって、これらの関数は、アプリケーションが保守的に動作して信頼性を最大限に高めるのに役立つ、最悪のシナリオを理解するのに役立ちます。 値は概算であり、OS のバージョンによって異なる場合があります。

ヒープ メモリ割り当ての追跡を追加する

ヒープ メモリ割り当て追跡を追加することで、追加のメモリ使用量情報を取得できます。これは、静的および動的にリンクされたライブラリによって行われているユーザーとカーネルの割り当てを示します。 これにより、メモリを最も効果的に使用するのに役立つアプリケーションでメモリが使用されている場所をより詳細に把握できます。 この機能は、Azure Sphere OS バージョン 21.07 以降とアプリケーション ランタイム バージョン (ARV) 10 以降で使用でき、開発が有効なデバイスでのみ機能し、アプリケーションがデバッガーで実行 されていない 場合にのみ機能します。

メモ

ヒープ メモリ割り当ての追跡が正しく機能するには、このセクションで説明されている両方の構成タスクを完了する必要があります。 失敗した場合、コンパイル中に警告が報告され、ヒープ メモリ情報は表示されません。

ヒープ メモリ割り当ての追跡を有効にするには、次の 2 つの操作を行う必要があります。

  • HeapMemStats 機能をアプリケーションの app-manifest.json ファイルに追加します。

      "Capabilities": {
        "HeapMemStats": true
      },
    
  • アプリケーションの CMakeLists.txt ファイルの コマンドにを追加してazsphere_target_add_image、libmalloc ライブラリをイメージ パッケージに追加DEBUG_LIB "libmalloc"します。

    azsphere_target_add_image_package(${PROJECT_NAME} DEBUG_LIB "libmalloc")
    

大事な

ヒープ メモリ割り当ての追跡は開発が有効なデバイスでのみ機能するため、デプロイ用のイメージ パッケージをビルドする前に、アプリケーションから削除するには、次の操作を行う必要があります。

  • アプリケーションの app-manifest.json ファイルから行 '"HeapMemStats": true' を削除します。
  • アプリケーションの azsphere_target_add_image_package(${PROJECT_NAME} DEBUG_LIB "libmalloc" CMakeLists.txt ファイルのコマンドから削除DEBUG_LIB "libmalloc"します。

Visual Studio パフォーマンス プロファイラーを使用する

Visual Studio を使用する場合は、パフォーマンス プロファイラー機能を使用して、アプリケーション メモリの使用状況に関する情報を取得できます。 このプロファイラーを使用するチュートリアルについては、「 Tutorials/MemoryUsage」を参照してください。

前提 条件

メモリ使用量プロファイラーを開始する

  1. [デバッグ パフォーマンス プロファイラー]> を選択するか、Alt キーを押しながら F2 キーを押してパフォーマンス プロファイラーの開始ウィンドウを開きます。

    Visual Studio のパフォーマンス プロファイラー ウィンドウ

  2. [ 分析ターゲット] の [ Azure Sphere Device Profiler ] が表示されない場合は、[ ターゲットの選択 ] を選択し、[ Azure Sphere Device Profiler] を選択します。

  3. [ 使用可能なツール] で、[ Azure Sphere メモリ使用量 ] がオンになっていることを確認し、[ 開始 ] を選択してメモリ使用量プロファイル ウィンドウを開き、メモリ プロファイラーを起動します。

  4. アプリケーションをデプロイまたは再起動する必要がある場合は、[デバッグなしでデバッグ>の開始] を選択するか、Ctrl キーを押しながら F5 キーを押してアプリケーションをデバイスにデプロイします。

    大事な

    アプリケーションの正確な RAM 使用状況情報を取得するには、[デバッグ なしで アプリを起動する](buid-hl-app.md#build-and-deploy-the-application-in- visual-studio-without-debugging) することが重要です。 デバッガーでアプリを実行すると、デバッグ サーバーによって消費されるメモリが報告された RAM 使用率の統計情報に含まれるため、RAM 使用量が膨らみます。

メモリ使用量プロファイラー データの解釈

メモリ使用量プロファイル ウィンドウには、次のようなビューが表示されます。

Visual Studio のメモリ使用量プロファイラー ウィンドウ

ビューの中央にある Azure Sphere Device Physical Memory グラフは、アプリの実行中に 3 つの異なる RAM 使用状況統計 (最も近い KiB に表示) を 3 つの異なる行としてプロットします。

  • 合計: アプリまたはデバッグ サーバーに代わってカーネル割り当て (ソケットのバッファーなど) を含む、システム上のアプリの物理メモリ使用量の合計。
  • ユーザー: アプリによって直接使用される物理メモリの量、その代わりに任意のライブラリによって使用されるメモリ ( アノン 割り当てとも呼ばれます)、デバッグ サーバーによって使用されるメモリ。
  • ピーク ユーザー: 現在のセッションで使用されるユーザー メモリの最大量。 アプリケーションのメモリ使用量をテストするときは、この値が 256 KiB を超えないようにする必要があります。 追加のメモリは、カーネル割り当て用に予約されています。 この値は、アプリが再起動または再デプロイされるたびにリセットされます。

グラフには、New Peak イベント (三角形で表される) の発生もプロットされます。 このイベントは、ピーク 時のユーザー メモリ使用量の新しい最大値が発生するたびに発生します。 このイベントは、スクリーン リーダーのアクセシビリティに対して有効になっています。

ヒープ メモリ割り当て追跡を有効にしていて、アプリケーションがデバッガーで実行されていない場合は、ヒープ メモリ統計を示す追加のグラフが表示されます。

  • 合計ヒープ: 静的および動的ライブラリを含む、アプリケーションによって、またはアプリケーションの代わりに割り当てられたヒープ メモリの合計。
  • 共有ライブラリ ヒープ: Azure Sphere OS によって提供される動的にリンクされたライブラリからの割り当て。

Visual Studio のヒープ メモリ使用量

グラフの上にあるタイムライン ビューには、アプリの実行時間が表示され、下のグラフのデータと関連付けられます。 特定 期間にフォーカスを合わせるには、[拡大] と [縮小] を使用します。

グラフの下には、テーブル ビューに同じメモリ統計とイベントが表示されます。

ヒント

テーブルからクリップボードにデータをコピーするには、 Ctrl + A キー を押してすべての行を選択し、 Ctrl + C キーを押します。

このセクションで示す最初の 2 つのグラフは、メモリ リークを含む メモリ使用量チュートリアルのステージ 1 の実行中に作成されました。 メモリ使用量は各グラフで単調に上昇し、リークの視覚的証拠を提供します。 メモリ 使用量のチュートリアルのステージ 2 のように、リークが修正されると、メモリが割り当てられ、割り当て解除されるとグラフが上昇および低下します。

メモリ リークのない Visual Studio ヒープ メモリ使用量

メモリ使用量の合計に関する統計情報を表示する

az sphere device app show-memory-stats コマンドは、接続されているデバイスで実行されているアプリケーションの合計メモリ使用量、ユーザー モード使用率、およびピーク ユーザー モード使用率に関するメモリ使用量の統計情報を返します。 デバイスには、このコマンドを実行するように appDevelopment デバイス機能が構成されている必要があります。

アプリの実行中に表示される RAM 使用率の統計情報は次のとおりです。

  • Total (Kernel + User Mode): アプリまたはデバッグ サーバーに代わってカーネル割り当て (ソケットのバッファーなど) を含む、システム上のアプリの物理メモリ使用量の合計。
  • ユーザー モード: アプリによって直接使用される物理メモリの量、その代わりに任意のライブラリによって使用されるメモリ ( アノン 割り当てとも呼ばれます)、デバッグ サーバーによって使用されるメモリ。
  • ピーク ユーザー モード: 現在のセッションで使用されるユーザー メモリの最大量。 アプリケーションのメモリ使用量をテストするときは、この値が 256 KiB を超えないようにする必要があります。 追加のメモリは、カーネル割り当て用に予約されています。 この値は、アプリが再起動または再デプロイされるたびにリセットされます。

ヒープ メモリ割り当て追跡を有効にしていて、アプリケーションがデバッガーで実行されていない場合は、ヒープ メモリ統計の追加行が表示されます。

  • ヒープ: アプリと静的ライブラリ: コードとそれに静的にリンクされたライブラリからのカーネルとユーザーの割り当て。
  • ヒープ: <動的ライブラリの>割り当て: Azure Sphere OS によって提供される個々の動的にリンクされたライブラリからの割り当て。

メモリ使用量の継続的な監視

時間の経過に伴うメモリ使用量を監視するには、スクリプトを使用して [az sphere device app show-memory-stats](.) を実行できます。/reference/az sphere-device.md) コマンドをループ内で実行します(次の例を参照)。

Windows コマンド プロンプト

メモ帳または別のテキスト エディターを使用して、次の内容を含むバッチ スクリプト ファイル memuse.bat を作成します。

@echo off

:loop
call az sphere device app show-memory-stats
choice /d y /t 1 > nul
goto loop

コマンド プロンプトで名前を入力してバッチ スクリプトを実行します (または、ファイルが現在のディレクトリにない場合はファイルの完全なパス)。

C:\Users\username> memuse.bat
 -------------------------- -------------
 Name                       Usage (bytes)
 ========================================
 Total (Kernel + User Mode) 65536
 -------------------------- -------------
 User Mode                  36864
 -------------------------- -------------
 Peak User Mode             36864
 -------------------------- -------------
 -------------------------- -------------
 Name                       Usage (bytes)
 ========================================
 Total (Kernel + User Mode) 65536
 -------------------------- -------------
 User Mode                  36864
 -------------------------- -------------
 Peak User Mode             36864
 -------------------------- -------------

スクリプトを終了するには、コマンド プロンプト ウィンドウで「Ctrl + C」と入力し、"バッチ ジョブの終了" プロンプトに対して Y と答えます。

Windows PowerShell

while ($true) {
    az sphere device app show-memory-stats
    Start-Sleep -Seconds 1
}

メモリ使用量とデバッガー

デバッガーでアプリを実行する場合、報告されるメモリ統計には、デバッグ サーバー プロセスのメモリ使用量や、ブレークポイントの設定など、デバッグによって引き起こされるその他のメモリ使用量も含まれます。 このため、正確なメモリ統計を収集しようとするときは、デバッグを行わずにアプリを常に実行する必要があります。

ただし、デバッガーでアプリを実行する場合は、メモリ使用量プロファイラーを使用すると便利です。 メモリ使用量の相対的な変化を観察しながらブレークポイントを設定し、コード行をステップ実行すると、メモリ使用量の急増やメモリ リークの原因を特定するのに便利な手法になります。

Visual Studio でデバッグする場合、パフォーマンス プロファイラーは自動的に開きますが、ヒープ メモリ割り当ての追跡は表示されません。