.NET オブジェクト割り当てツールを使用してメモリ使用量を分析する

.NET オブジェクト割り当てツールを使用して、アプリで使用されているメモリの量と、最も多くのメモリを割り当てるコード パスを確認できます。

ツールを実行すると、オブジェクトが割り当てられている関数の実行パスが表示されます。 その後、最も多くのメモリを占有している呼び出しツリーのルートまでトレースすることができます。

.NET オブジェクト割り当てツールを使用してパフォーマンスを向上させる方法を説明するチュートリアルについては、「コードの最適化に関する初心者向けガイド」を参照してください。

セットアップ

  1. Alt + F2 キーを押して Visual Studio でパフォーマンス プロファイラーを開きます。

  2. [.NET オブジェクト割り当て追跡] チェック ボックスをオンにします。

    [.NET オブジェクト割り当て追跡] ツールが選ばれたスクリーンショット。

    [.NET オブジェクト割り当て追跡] ツールが選ばれたスクリーンショット。

  3. [開始] ボタンを選択してツールを実行します。

    プロファイラーを起動する前に [コレクションを一時停止した状態で開始] オプションを有効にした場合、診断セッション ビューで [記録] ボタンを選択するまでデータは収集されません。

  4. ツールの実行が開始されたら、アプリ内でプロファイリングするシナリオを検討します。 次に、 [収集の停止] を選択するかアプリを閉じてデータを確認します。

    [収集の停止] を示すウィンドウのスクリーンショット。

    [収集の停止] を示すウィンドウのスクリーンショット。

  5. [割り当て] タブを選びます。次のようなメモリ割り当てデータが表示されます。

    [割り当て] タブのスクリーンショット。

    [割り当て] タブのスクリーンショット。

これで、オブジェクトのメモリ割り当てを分析できるようになりました。

コレクション中に、プロファイリングされたアプリが追跡ツールによって低速になることがあります。 追跡ツールまたはアプリのパフォーマンスが低下している場合や、すべてのオブジェクトを追跡する必要がない場合は、サンプリング レートを調整できます。 これを行うには、プロファイラーの概要ページで、追跡ツールの横にある歯車アイコンを選択します。

.NET 割り当てツール設定のスクリーンショット。

.NET 割り当てツール設定のスクリーンショット。

サンプリング レートを希望のレートに調整します。 この変更により、コレクションと分析中にアプリのパフォーマンスを向上させることができます。

調整されたサンプリング レートのスクリーンショット。

調整されたサンプリング レートのスクリーンショット。

ツールの効率を向上させる方法の詳細については、「プロファイラー設定の最適化」を参照してください。

データを理解する

次のグラフィック ビューでは、上部のグラフにアプリ内のライブ オブジェクトの数が表示されます。 下の [オブジェクトの差分] グラフには、アプリ オブジェクトの変化率が表示されます。 赤色のバーは、ガベージ コレクションがいつ行われたかを表します。

.NET 割り当てツール グラフのスクリーンショット。

.NET 割り当てツール グラフのスクリーンショット。

時間の範囲を選んで表形式データをフィルター処理し、指定した時間の範囲のアクティビティだけを表示できます。 この操作を行うと、タブに表示される情報は、フィルター処理された時間の範囲に限られます。

.NET 割り当て時間のフィルター処理されたグラフのスクリーンショット。

.NET 割り当て時間のフィルター処理されたグラフのスクリーンショット。

グラフを拡大または縮小表示することもできます。

割り当て

[割り当て] ビューには、メモリを割り当てているオブジェクトの場所と、それらのオブジェクトによって割り当てられているメモリの量が表示されます。

展開された [割り当て] ビューのスクリーンショット。

展開された [割り当て] ビューのスクリーンショット。

以下の情報が [割り当て] ビューに表示されます。

  • [種類] 列は、メモリを占有しているクラスと構造体の一覧です。 種類をダブルクリックし、そのバックトレースを逆呼び出しツリーとして表示します。 [割り当て] ビューでのみ、選択したカテゴリ内の、メモリを占有している項目を表示できます。

  • [割り当て] 列には、メモリを占有している、特定の割り当ての種類または関数に含まれるオブジェクトの数が表示されます。 この列が表示されるのは、 [割り当て][呼び出しツリー][関数] ビューだけです。

  • 既定では、 [バイト] および [平均サイズ (バイト)] 列は表示されません。 これらを表示するには、 [種類] または [割り当て] 列を右クリックしてから、 [バイト] および [平均サイズ (バイト)] オプションを選択して、それらをグラフに追加します。

    この 2 つの列は [合計 (割り当て)][自己 (割り当て)] に似ていますが、メモリを占有しているオブジェクトの数ではなく、占有されているメモリの量が表示されています。 これらの列は [割り当て] ビューにのみ表示されます。

  • [モジュール名] 列には、呼び出している関数またはプロセスを含むモジュールが表示されます。

これらの列はすべて並べ替え可能です。 [種類] および [モジュール名] 列では、アルファベットの昇順または降順で項目を並べ替えることができます。 [割り当て][バイト][平均サイズ (バイト)] では、数値を増減して項目を並べ替えることができます。

シンボル

[割り当て][呼び出しツリー] 、および [関数] タブには、次のシンボルが表示されます。

  • 値の型シンボル - 整数などの値の型

  • 値型コレクション シンボル - 整数の配列のような値型コレクション

  • 参照型シンボル - 文字列などの参照型

  • 参照型コレクション シンボル - 文字列の配列のような参照型コレクション

呼び出しツリー

[呼び出しツリー] ビューには、大量のメモリを割り当てているオブジェクトを含む関数の実行パスが表示されます。

呼び出しツリー ビューのスクリーンショット。

呼び出しツリー ビューのスクリーンショット。

以下の情報が [呼び出しツリー] ビューに表示されます。

  • [関数名] 列には、メモリを割り当てるオブジェクトを含む関数のプロセスまたは名前が表示されます。 表示は、調査しているノードのレベルに基づいています。
  • [合計 (割り当て)][合計サイズ (バイト)] 列には、割り当てられたオブジェクトの数と、関数およびその関数によって呼び出された他のすべての関数で使用されているメモリの量が表示されます。 [合計サイズ (バイト)] 列は既定では非表示です。
  • [自己 (割り当て)] および [自己サイズ (バイト)] 列には、割り当てられたオブジェクトの数と、選択された単一の関数または割り当ての種類で使用されているメモリの量が表示されます。
  • [平均サイズ (バイト)] 列には、 [割り当て] ビューと同じ情報が表示されます。 この列は既定で非表示になります。
  • [モジュール名] 列には、呼び出している関数またはプロセスを含むモジュールが表示されます。

[呼び出しツリー] ビューに表示されるその他のオプションは次のとおりです。

  • [ホット パスの展開] ボタンをクリックすると、メモリを割り当てているオブジェクトを数多く含む関数の実行パスが強調表示されます。 このアルゴリズムは、ユーザーが選択したノードで開始され、ほとんどの割り当てのパスを強調表示して、ユーザーの調査をガイドします。
  • [ホット パスの表示] ボタンをクリックすると、ホット パスの一部であるノードを示す炎アイコンの表示と非表示が切り替わります。

展開されたホット パスのスクリーンショット。

展開されたホット パスのスクリーンショット。

関数

[関数] ビューには、メモリを割り当てているプロセス、モジュール、および関数が表示されます。

[関数] ビューのスクリーンショット。

[関数] ビューのスクリーンショット。

[関数] ビューに表示される情報には、次のものが含まれます。

  • [名前] 列には、最上位レベルのノードとしてプロセスが表示されます。 プロセスの下にモジュールがあり、モジュールの下に関数があります。

  • 次の列には、[割り当て] および [呼び出しツリー] ビューと同じ情報が表示されます。

    • 合計 (割り当て)
    • 自己 (割り当て)
    • 合計サイズ (バイト)
    • 自己サイズ (バイト)
    • 平均サイズ (バイト)

コレクション

[コレクション] ビューには、ガベージ コレクション中に収集または保持されていたオブジェクトの数が表示されます。

[コレクション] ビューのスクリーンショット。

[コレクション] ビューのスクリーンショット。

以下の情報が [コレクション] ビューに表示されます。

  • [GC] 列には、実行可能ファイルのライフサイクルにおける、このガベージ コレクションの ID が表示されます。
  • [世代] 列には、ガベージ コレクションの世代が表示されます。
  • [GC の種類] 列には、ガベージ コレクションの種類が表示されます。
  • [GC の理由] 列には、ガベージ コレクション イベントの理由が表示されます。
  • [一時停止の期間] 列には、ガベージ コレクターでヒープを排他的に使用する必要があるため、実行がブロックされた時間が表示されます。 バックグラウンド ガベージ コレクションの場合、この値は小さくなります。
  • [LOH サイズ] 列には、ガベージ コレクター実行後のラージ オブジェクト ヒープのサイズが表示されます。
  • [POH サイズ] 列には、ガベージ コレクター実行後の固定されたオブジェクト ヒープのサイズが表示されます。
  • [ファイナライズ可能な Surv (MB)] 列には、ガベージ コレクションで存続したファイナライザー (デストラクター) を持つオブジェクトの MB 数が表示されます。
  • [固定されたオブジェクト] 列には、このガベージ コレクションによって昇格された、固定されたオブジェクトの数が表示されます。
  • [収集済み] 列には、ガベージ コレクターによって収集されたオブジェクトの数が表示されます。
  • [残り] 列には、ガベージ コレクターの実行後に残ったオブジェクトの数が表示されます。

行を選ぶと、このビューには収集されたオブジェクトと存続したオブジェクトを種類別に視覚化した円グラフも表示されます。

[コレクション] ビューの円グラフのスクリーンショット。

フィルター処理ツール

[割り当て][呼び出しツリー][関数] ビューのすべてに、 [マイ コードのみ表示][Show Native Code](ネイティブ コードを表示) オプションとフィルター ボックスが含まれています。

  • [マイコードのみ表示] を選択すると、システム、フレームワーク、およびその他の非ユーザーコードが [外部コード] フレームに折りたたまれるので、ユーザーコードに焦点を当てることができます。 詳細については、マイ コードのみを使用したユーザー コードのデバッグに関する記事を参照してください。
  • [Show Native Code](ネイティブ コードを表示) を選択すると、非ユーザー コードを含む分析ターゲット内のネイティブ コードが表示されます。
  • フィルター ボックスを使用すると、指定した値に基づいて [名前] または [関数名] 列をフィルター処理できます。 ボックスに文字列値を入力してください。 テーブルに、その文字列を含む種類のみが表示されます。