パフォーマンス プロファイラーでメモリ使用量をデバッグなしで分析する (C#、Visual Basic、C++、F#)
メモリ使用量ツールでは、アプリのメモリ使用量を監視します。 ツールを使用して、Visual Studio で積極的に開発を行っているシナリオによるリアルタイムのメモリへの影響を調べることできます。 アプリのメモリ状態の詳細なスナップショットを取得し、そのスナップショットを比較してメモリの問題の根本原因を見つけることができます。 メモリ使用量ツールは、.NET アプリ、ASP.NET アプリ、C++ アプリ、または混在モード (.NET とネイティブ) アプリでサポートされています。
メモリ使用量ツールは、デバッガーの有無に関わらず実行できます。 この記事では、Visual Studio パフォーマンス プロファイラーでデバッガーなしでメモリ使用量ツールを使用する方法を示します。これは、リリース ビルドに推奨されます。 ニーズに最適なメモリ分析ツールを選択する方法については、「メモリ分析ツールの選択」を参照してください。
メモリ使用量診断セッション
メモリ使用量診断セッションを開始するには:
Visual Studio でプロジェクトを開きます。
メモリ使用量ツールは、.NET アプリ、ASP.NET アプリ、C++ アプリ、または混在モード (.NET とネイティブ) アプリをサポートしています。
デバッグ メニューで、ソリューション構成を [リリース] に設定し、配置ターゲットとして [ローカル Windows デバッガー] (または [ローカル コンピューター]) を選択します。
メニュー バーで、[デバッグ]>[パフォーマンス プロファイラー] を選びます。
[使用可能なツール] の下で、[メモリ使用量] を選択し、[開始] を選択します。
メモリ使用量の監視
診断セッションを開始すると、アプリが起動し、診断ツール ウィンドウにアプリのメモリ使用量のタイムライン グラフが表示されます。
タイムライン グラフには、アプリの実行中のメモリの変動が示されます。 グラフの急な上下動は、通常、何らかのコードでデータが収集または作成され、処理が終わったときにデータが破棄されていることを示します。 大きな上下動は、最適化できる領域を示しています。 主な問題は、使われたまま返されないメモリが増えることです。 これは、メモリが効率的に使われていないか、メモリ リークが起きていることを示す場合があるためです。
アプリのメモリ状態のスナップショットを取得する
アプリでは数多くのオブジェクトが使用されますが、1 つのシナリオを集中的に分析することができます。 メモリの問題を検出して調べることもできます。 診断セッション中にスナップショットを取得し、特定の時点のメモリ使用量をキャプチャすることができます。 メモリの問題が発生する前に、アプリのベースライン スナップショットを取得することをお勧めします。 初めて問題が起きた後でもう 1 回スナップショットを取得し、シナリオを繰り返せる場合は追加のスナップショットを取得することができます。
スナップショットを収集するには、メモリ データをキャプチャしたいときに [スナップショットの取得] を選択します。
診断セッションを閉じる
レポートを作成せずに監視セッションを停止する場合は、単に診断ウィンドウを閉じます。 スナップショットの収集が完了したとき、またはスナップショットを取得したときにレポートを生成するには、[コレクションの停止] を選択します。
データの収集または表示に問題がある場合は、「プロファイル エラーのトラブルシューティングと問題の修正」をご覧ください。
メモリ使用量レポート
データ収集を停止すると、メモリ使用量ツールでアプリが停止され、メモリ使用量の概要ページが表示されます。
メモリ使用量のスナップショット
[スナップショット] ウィンドウの数値は、各スナップショットが取得されたときのメモリ内のオブジェクトとバイト、およびあるスナップショットとその前のものとの相違を示します。
数値は、新しい Visual Studio ウィンドウで詳細なメモリ使用量レポート ビューを開くリンクになっています。 スナップショットの詳細レポートには、1 つのスナップショット内の種類とインスタンスが表示されます。 スナップショットの相違 (diff) レポートでは、2 つのスナップショット内の種類とインスタンスが比較されます。
Image | 説明 |
---|---|
![]() |
スナップショット取得時のメモリ内のバイトの合計数。 このリンクを選択すると、スナップショットの詳細レポートが各種類のインスタンスの合計サイズ順に並べ替えて表示されます。 |
![]() |
スナップショット取得時のメモリ内のオブジェクトの合計数。 このリンクを選択すると、スナップショットの詳細レポートが各種類のインスタンス数の順に並べ替えて表示されます。 |
![]() |
このスナップショットと前のスナップショットとのメモリ オブジェクトの合計サイズの差。 正の数はこのスナップショットのメモリ サイズが前のものより大きいことを意味し、負の数はサイズがより小さいことを意味します。 [ベースライン] は、スナップショットが診断セッションで最初のものであることを意味します。 [No Difference]\(相違なし\) は、差が 0 であることを意味します。 このリンクを選択すると、スナップショットの相違レポートが各種類のインスタンスの合計サイズの差の順に並べ替えて表示されます。 |
![]() |
このスナップショットと前のスナップショットとのメモリ オブジェクトの合計数の差。 このリンクを選択すると、スナップショットの相違レポートが表示されます。 これは、各種類のインスタンスの合計数の差の順に並べ替えて表示されます。 |
Image | 説明 |
---|---|
![]() |
スナップショット取得時のメモリ内のオブジェクトの合計数。 このリンクを選択すると、スナップショットの詳細レポートが各種類のインスタンス数の順に並べ替えて表示されます。 |
![]() |
このスナップショットと前のスナップショットとのメモリ オブジェクトの合計数の差。 このリンクを選択すると、スナップショットの相違レポートが各種類のインスタンスの合計数の差の順に並べ替えて表示されます。 |
![]() |
スナップショット取得時のメモリ内のバイトの合計数。 このリンクを選択すると、スナップショットの詳細レポートが各種類のインスタンスの合計サイズ順に並べ替えて表示されます。 |
![]() |
このスナップショットと前のスナップショットとのメモリ オブジェクトの合計サイズの差。 正の数はこのスナップショットのメモリ サイズが前のものより大きいことを意味し、負の数はサイズがより小さいことを意味します。 [ベースライン] は、スナップショットが診断セッションで最初のものであることを意味します。 [No Difference]\(相違なし\) は、差が 0 であることを意味します。 このリンクを選択すると、スナップショットの相違レポートが各種類のインスタンスの合計サイズの差の順に並べ替えて表示されます。 |
メモリ使用量のスナップショット レポート
メモリ使用量の概要ページでスナップショット リンクのいずれかを選択すると、新しいページにスナップショット レポートが開きます。
[オブジェクトの種類] が青色の場合は、それを選択し、別のウィンドウで、ソース コードのオブジェクトに移動することができます。
識別できない種類や、理解できないコードに関連する種類は、.NET、オペレーティング システム、あるいはコンパイラのオブジェクトと考えられます。 これらのオブジェクトは、オブジェクトの所有権の継承に関連する場合、メモリ使用量ツールに表示されます。
スナップショット レポートでは:
[マネージド メモリ] ツリーに、レポート内の種類とインスタンスが表示されます。 種類またはインスタンスを選ぶと、選んだ項目の [ルートのパス] ツリーと [参照されたオブジェクト] ツリーが表示されます。
[ルートのパス] ツリーには、種類またはインスタンスを参照するオブジェクトのチェーンが表示されます。 オブジェクトへの参照がすべて解放された場合にのみ、.NET のガベージ コレクターによってそのメモリがクリーンアップされます。
[参照された型] ツリーまたは [参照されたオブジェクト] ツリーには、選んだ型またはインスタンスによって参照されるオブジェクトが表示されます。
レポート ツリー フィルター
アプリの多くの種類は、アプリ開発者には必要ありません。 スナップショット レポート フィルターでは、[マネージド メモリ] ツリーと [ルートのパス] ツリーのこれらの種類のほとんどを非表示にすることができます。
ツリーを種類名でフィルター処理するには、[フィルター] ボックスに名前を入力します。 このフィルターでは大文字と小文字は区別されず、指定された文字列が種類名のどこかに含まれていれば認識されます。
[フィルター] ドロップダウンで [小さいオブジェクトを折りたたむ] を選択すると、[サイズ (バイト)] が合計メモリの 0.5% 未満の種類が非表示になります。
[フィルター] ドロップダウンの [マイ コードのみ] を選択すると、外部コードによって生成されたほとんどのインスタンスが非表示になります。 外部の種類は、オペレーティング システムまたはフレームワーク コンポーネントに属しているか、コンパイラによって生成されます。
スナップショットの詳細レポート
スナップショットの詳細レポートでは、診断セッションで得られた 1 つのスナップショットについて説明されます。 レポートを開くには、スナップショット ウィンドウでサイズまたはオブジェクトのリンクを選択します。
両方のリンクで同じレポートが開きます。 [マネージド メモリ] ツリーを最初に表示したときの並べ替え順序だけが異なります。 サイズ リンクでは、[包括サイズ (バイト)] 列でレポートが並べ替えられます。 オブジェクト リンクでは、[カウント] 列でレポートが並べ替えられます。 レポートが開いた後で並べ替え列や順序を変更することができます。
マネージド メモリ ツリー (スナップショットの詳細レポート)
[マネージド メモリ] ツリーには、メモリ内に保持されているオブジェクトの種類が一覧表示されます。 種類名を展開すると、サイズ順に、その種類の最大のインスタンスが 10 個表示されます。 種類またはインスタンスを選ぶと、選んだ項目の [ルートのパス] ツリーと [参照されたオブジェクト] ツリーが表示されます。
スナップショットの詳細レポートの [マネージド メモリ] ツリーには、次の列があります。
名前 | 説明 |
---|---|
オブジェクトの種類 | 型またはオブジェクト インスタンスの名前。 |
Count | 型のオブジェクト インスタンス数。 インスタンスの場合、[カウント] は常に 1 です。 |
サイズ (バイト) | 種類の場合は、スナップショット内のその種類のすべてのインスタンスのサイズ (インスタンスに含まれているオブジェクトのサイズは除く)。インスタンスの場合は、オブジェクトのサイズ (インスタンスに含まれているオブジェクトのサイズは除く)。 |
包括サイズ (バイト) | 種類のインスタンスのサイズ、または単一インスタンスのサイズ (含まれているオブジェクトのサイズを含む)。 |
モジュール | オブジェクトを含むモジュール。 |
ルート ツリーへのパス (スナップショットの詳細レポート)
[ルートのパス] ツリーには、種類またはインスタンスを参照するオブジェクトのチェーンが表示されます。 オブジェクトへの参照がすべて解放された場合にのみ、.NET のガベージ コレクターによってそのメモリがクリーンアップされます。
[ルートのパス] ツリーの種類の場合、その種類への参照を保持するオブジェクトの数が [参照数] 列に示されます。
[参照された型] または [参照先オブジェクト] ツリー (スナップショットの詳細レポート)
[参照された型] ツリーまたは [参照されたオブジェクト] ツリーには、選んだ型またはインスタンスによって参照されるオブジェクトが表示されます。
スナップショットの詳細レポートの [参照された型] ツリーには、次の列があります。 [参照されたオブジェクト] ツリーには、[参照数] 列はありません。
名前 | 説明 |
---|---|
オブジェクトの種類またはインスタンス | 種類またはインスタンスの名前。 |
参照数 | 種類の場合は、その種類のオブジェクト インスタンスの数。 |
サイズ (バイト) | 種類の場合は、その種類のすべてのインスタンスのサイズ (種類に含まれているオブジェクトのサイズは除く)。 インスタンスの場合は、オブジェクトのサイズ (オブジェクトに含まれているオブジェクトのサイズは除く)。 |
包括サイズ (バイト) | 種類のインスタンスの合計サイズ、またはインスタンスのサイズ (含まれているオブジェクトのサイズを含む)。 |
モジュール | オブジェクトを含むモジュール。 |
スナップショットの相違 (diff) レポート
スナップショットの相違 (diff) レポートには、指定したスナップショットと前のスナップショットの変更点が表示されます。 相違レポートを開くには、スナップショット ウィンドウで相違リンクのいずれかを選択します。
両方のリンクで同じレポートが開きます。 レポートの [マネージド メモリ] ツリーを最初に表示したときの並べ替え順序だけが異なります。 サイズ リンクでは、[包括サイズの相違 (バイト)] 列でレポートが並べ替えられます。 オブジェクト リンクでは、[数の相違] 列でレポートが並べ替えられます。 レポートが開いた後で並べ替え列や順序を変更することができます。
マネージド メモリ ツリー (スナップショット差分レポート)
[マネージド メモリ] ツリーには、メモリ内に保持されているオブジェクトの種類が一覧表示されます。 種類名を展開すると、サイズ順に、その種類の最大のインスタンスが 10 個表示されます。 種類またはインスタンスを選ぶと、選んだ項目の [ルートのパス] ツリーと [参照されたオブジェクト] ツリーが表示されます。
スナップショットの相違レポートの [マネージド メモリ] ツリーには、次の列があります。
名前 | 説明 |
---|---|
オブジェクトの種類 | 型またはオブジェクト インスタンスの名前。 |
Count | 指定したスナップショットに含まれる型のインスタンス数。 インスタンスの場合、[カウント] は常に 1 です。 |
数の相違 | 型の場合は、指定したスナップショットと前のスナップショットとの、型のインスタンス数の差。 インスタンスの場合、このフィールドは空白です。 |
サイズ (バイト) | 指定したスナップショット内のオブジェクトのサイズ (オブジェクト内のオブジェクトのサイズは除く)。 型の場合、[サイズ (バイト)] と [包含サイズ (バイト)] は型インスタンスの合計サイズです。 |
合計サイズの相違 (バイト) | 種類の場合は、指定したスナップショットと前のスナップショットとの、その種類のインスタンスの合計サイズの差 (インスタンス内のオブジェクトのサイズは除く)。 インスタンスの場合、このフィールドは空白です。 |
包括サイズ (バイト) | 指定したスナップショット内のオブジェクトのサイズ (オブジェクト内のオブジェクトのサイズを含む)。 |
包括サイズの相違 (バイト) | 種類の場合は、指定したスナップショットと前のスナップショットとの、その種類のすべてのインスタンスのサイズの差 (オブジェクト内のオブジェクトのサイズを含む)。 インスタンスの場合、このフィールドは空白です。 |
モジュール | オブジェクトを含むモジュール。 |
ルート ツリーへのパス (スナップショット差分レポート)
[ルートのパス] ツリーには、種類またはインスタンスを参照するオブジェクトのチェーンが表示されます。 オブジェクトへの参照がすべて解放された場合にのみ、.NET のガベージ コレクターによってそのメモリがクリーンアップされます。
[ルートのパス] ツリーの種類の場合、その種類への参照を保持するオブジェクトの数が [参照数] 列に示されます。 前のスナップショットからの数の差は、[Reference Diff]\(参照の相違\) 列に示されます。
[参照された型] または [参照先オブジェクト] ツリー (スナップショット差分レポート)
[参照された型] ツリーまたは [参照されたオブジェクト] ツリーには、選んだ型またはインスタンスによって参照されるオブジェクトが表示されます。
スナップショットの相違レポートの [参照された型] ツリーには、次の列があります。 [参照されたオブジェクト] ツリーには、[インスタンス]、[サイズ (バイト)]、[包括サイズ (バイト)]、および [モジュール] という列があります。
名前 | 説明 |
---|---|
オブジェクトの種類またはインスタンス | 型またはオブジェクト インスタンスの名前。 |
参照数 | 指定したスナップショットに含まれる型のインスタンス数。 |
参照数の相違 | 型の場合は、指定したスナップショットと前のスナップショットとの、型のインスタンス数の差。 |
サイズ (バイト) | 指定したスナップショット内のオブジェクトのサイズ (オブジェクト内のオブジェクトのサイズは除く)。 型の場合、[サイズ (バイト)] と [包含サイズ (バイト)] は型インスタンスの合計サイズです。 |
合計サイズの相違 (バイト) | 種類の場合は、指定したスナップショットと前のスナップショットとの、その種類のインスタンスの合計サイズの差 (インスタンス内のオブジェクトのサイズは除く)。 |
包括サイズ (バイト) | 指定したスナップショット内のオブジェクトのサイズ (オブジェクト内のオブジェクトのサイズを含む)。 |
包括サイズの相違 (バイト) | 種類の場合は、指定したスナップショットと前のスナップショットとの、その種類のすべてのインスタンスのサイズの差 (オブジェクト内のオブジェクトのサイズを含む)。 |
モジュール | オブジェクトを含むモジュール。 |
インサイト レポート
Visual Studio 2022 では、メモリ分析ツールによって、マネージド メモリに関する複数の強力な組み込みの自動分析情報も提供されます。 マネージド型レポートで [分析情報] タブを選ぶと、[重複文字列]、[スパース配列]、[イベント ハンドラー リーク] などの適用可能な自動分析情報が表示されます。 詳細については、「メモリ使用量分析情報」を参照してください。