次の方法で共有


リリース ビルドでのメモリ使用量の分析 (C#、Visual Basic、C++、F#)

メモリ使用量 ツールは、アプリのメモリ使用量を監視します。 このツールを使用して、Visual Studio で積極的に開発しているシナリオのリアルタイム メモリ効果を調査できます。 アプリのメモリ状態の詳細なスナップショットを取得し、スナップショットを比較してメモリの問題の根本原因を見つけることができます。 メモリ使用量ツールは、.NET、ASP.NET、C++、または混合モード (.NET およびネイティブ) アプリでサポートされています。

メモリ使用量ツールはリリース ビルドまたはデバッグ ビルドで実行できます。 この記事では、リリース ビルドに推奨される Visual Studio Performance Profilerのメモリ使用量ツールを使用する方法について説明します。 ニーズに最適なメモリ分析ツールの選択については、「メモリ分析ツールを選択する」を参照してください。

このドキュメントで最適なエクスペリエンスを得る場合は、記事の上部にある一覧から好みの開発言語またはランタイムを選択してください。

メモリ使用量の診断セッション

メモリ使用量診断セッションを開始するには:

  1. Visual Studio でプロジェクトを開きます。

    メモリ使用量ツールは、.NET、ASP.NET、C++、または混合モード (.NET およびネイティブ) アプリをサポートします。

  2. [デバッグ] メニューで、ソリューション構成を [リリース に設定し、展開ターゲットとして [ローカル Windows デバッガー (またはローカル コンピューター ) 選択します。

  3. メニュー バーで、[デバッグ] >[パフォーマンス プロファイラー]選択します。

  4. 使用可能なツール で、[メモリ使用量] を選択してから、[スタート] を選択します。

    メモリ使用量診断セッションを開始します。

    メモリ使用量診断セッションを開始します。 を開始する

メモリ使用量の監視

診断セッションを開始すると、アプリが開始され、診断ツール ウィンドウにアプリのメモリ使用量のタイムライン グラフが表示されます。

アプリのメモリ使用量のタイムライン グラフを示す Visual Studio パフォーマンス プロファイラーの [診断ツール] ウィンドウのスクリーンショット。

アプリのメモリ使用量のタイムライン グラフを示す Visual Studio パフォーマンス プロファイラーの [診断ツール] ウィンドウのスクリーンショット。

タイムライン グラフには、アプリの実行中のメモリの変動が表示されます。 通常、グラフのスパイクは、一部のコードがデータを収集または作成し、処理が完了したときにデータを破棄していることを示しています。 大きなスパイクは、最適化できる領域を示します。 主な懸念事項は、返されないメモリ消費量の増加です。 これは、非効率的なメモリ使用量やメモリ リークを示している可能性があります。

アプリのメモリ状態のスナップショットを取得する

アプリは多数のオブジェクトを使用するため、分析を 1 つのシナリオに集中させることができます。 調査すべきメモリの問題が見つかるかもしれません。 診断セッション中にスナップショットを取得して、特定の時点でのメモリ使用量をキャプチャできます。 メモリの問題が発生する前に、アプリのベースライン スナップショットを取得することをお勧めします。 問題が最初に発生した後に別のスナップショットを作成し、シナリオを繰り返すことができる場合は追加のスナップショットを作成できます。

スナップショットを収集するには、メモリ データをキャプチャしたいときに [スナップショットの取得] を選択します。

スナップショットの作成のスクリーンショット。

診断セッションを閉じる

レポートを作成せずに監視セッションを停止するには、診断ウィンドウを閉じます。 スナップショットの収集が完了したとき、またはスナップショットを作成したときにレポートを生成するには、[収集の停止] 選択します。

コレクションを停止するスクリーンショット。

コレクションを停止するスクリーンショット。

データの収集または表示で問題が発生した場合は、「プロファイリング エラーのトラブルシューティングとの問題の修正」を参照してください。

メモリ使用量レポート

データ収集を停止すると、メモリ使用量 ツールによってアプリが停止され、メモリ使用量 概要ページが表示されます。

Visual Studio パフォーマンス プロファイラーのメモリ使用量ツールの概要ページのスクリーンショット。メモリ使用量グラフと 2 つのスナップショット ペインが表示されています。

Visual Studio パフォーマンス プロファイラーのメモリ使用量ツールの概要ページのスクリーンショット。メモリ使用量グラフと 2 つのスナップショット ペインが表示されています。

メモリ使用量のスナップショット

スナップショット ペインの数値には、各スナップショットの作成時のメモリ内のオブジェクトとバイト数、およびスナップショットと前のスナップショットの違いが表示されます。

この数値は、新しい Visual Studio ウィンドウ メモリ使用量 レポート ビューの詳細を開くリンクです。 スナップショットの詳細レポート には、1 つのスナップショット内の種類とインスタンスが表示されます。 スナップショットの相違 (差分) レポート、2 つのスナップショットの種類とインスタンスを比較します。

スナップショット ビュー リンクスナップショット ビュー リンクの スクリーンショット

C++ の場合、オブジェクト (Diff) 列の名前は Allocations (Diff)です。

画像 説明
手順 1 スナップショットが作成されたときのメモリ内のオブジェクトの合計数。 このリンクを選択すると、種類のインスタンス数で並べ替えられたスナップショットの詳細レポートが表示されます。
手順 2 このスナップショット内のメモリ オブジェクトの合計数と前のスナップショットの違い。 種類のインスタンスの合計数の差で並べ替えられたスナップショット差分レポートを表示するには、このリンクを選択します。
手順 3 スナップショットが作成されたときのメモリ内の合計バイト数。 このリンクを選択すると、種類のインスタンスの合計サイズで並べ替えられたスナップショットの詳細レポートが表示されます。
ステップ 4 このスナップショット内のメモリ オブジェクトの合計サイズと前のスナップショットの違い。 正の数値は、このスナップショットのメモリ サイズが前のスナップショットよりも大きいことを意味し、負の数はサイズが小さいを意味します。 ベースライン は、スナップショットが診断セッションの最初のスナップショットであることを意味します。 差なし は、差が 0 であることを意味します。 種類のインスタンスの合計サイズの差で並べ替えられたスナップショット差分レポートを表示するには、このリンクを選択します。

スナップショット ビュー リンクスナップショット ビュー リンク

画像 説明
手順 1 スナップショットが作成されたときのメモリ内の合計バイト数。 このリンクを選択すると、種類のインスタンスの合計サイズで並べ替えられたスナップショットの詳細レポートが表示されます。
手順 2 スナップショットが作成されたときのメモリ内のオブジェクトの合計数。 このリンクを選択すると、種類のインスタンス数で並べ替えられたスナップショットの詳細レポートが表示されます。
手順 3 このスナップショット内のメモリ オブジェクトの合計サイズと前のスナップショットの違い。 正の数値は、このスナップショットのメモリ サイズが前のスナップショットよりも大きいことを意味し、負の数はサイズが小さいを意味します。 ベースライン は、スナップショットが診断セッションの最初のスナップショットであることを意味します。 差なし は、差が 0 であることを意味します。 種類のインスタンスの合計サイズの差で並べ替えられたスナップショット差分レポートを表示するには、このリンクを選択します。
ステップ 4 このスナップショット内のメモリ オブジェクトの合計数と前のスナップショットの違い。 スナップショット差分レポートを表示するには、このリンクを選択します。 これは、型のインスタンスの合計数の差で並べ替えられます。

管理されたタイプのレポート

メモリ使用量の概要テーブルで、オブジェクト (Diff) セルの現在のリンクを選択します。

マネージドタイプ レポートのスクリーンショット。

手記

.NET コードの場合、ビュー インスタンス アイコン (オブジェクトの種類] 列のインスタンス アイコン) は、デバッガー統合メモリ使用量ツール を使用しているとき、または ヒープ スナップショット を開いて [マネージド メモリのデバッグ] 選択した場合にのみ使用できます。

上部のウィンドウには、スナップショット内の型の数とサイズ (型によって参照されるすべてのオブジェクトのサイズを含む) が表示されます (包括サイズ)。

下のペインの [ルートのパス] ツリーには、上のペインで選択されている型を参照するオブジェクトが表示されます。 .NET ガベージ コレクターは、オブジェクトを参照する最後の型が解放された場合にのみ、オブジェクトのメモリをクリーンアップします。 ルート ツリーへの パスの使用の詳細については、「ルートへのホット パスの分析」を参照してください。

マネージド タイプ レポートのスクリーンショット。

上部のウィンドウには、スナップショット内の型の数とサイズ (型によって参照されるすべてのオブジェクトのサイズを含む) が表示されます (包括サイズ)。

下のペインの [ルートのパス] ツリーには、上のペインで選択されている型を参照するオブジェクトが表示されます。 .NET ガベージ コレクターは、オブジェクトを参照する最後の型が解放された場合にのみ、オブジェクトのメモリをクリーンアップします。

参照型 ツリーには、上部ペインで選択した型によって保持されている参照が表示されます。

参照先オブジェクト レポートのスクリーンショット。

参照型 ツリーには、上部ペインで選択した型によって保持されている参照が表示されます。

参照先オブジェクト レポートのスクリーンショット。

レポート ツリー フィルター

アプリの開発者がメモリの問題を調査するために、アプリの多くの種類は必要ありません。 スナップショット レポート フィルターでは、マネージド メモリ およびルート ツリーへのパスの で、これらの種類の大部分を非表示にすることができます。

並べ替えとフィルターオプション

並べ替えとフィルターのオプション

  • 種類名でツリーをフィルター処理するには、[フィルター] ボックスに名前を入力します。 フィルターは大文字と小文字を区別せず、型名の任意の部分で指定された文字列を認識します。

  • [フィルター] ドロップダウンで [マイ コードのみ表示] を選択すると、外部コードによって生成されたほとんどのインスタンスが非表示になります。 外部型は、オペレーティング システムまたはフレームワーク コンポーネントに属しているか、コンパイラによって生成されます。

  • フィルター ドロップダウンで 小さいオブジェクトを折りたたむ を選択すると、サイズ (バイト) が合計メモリの 0.5% 未満の型が非表示になります。

ネイティブ型のレポート

[診断ツール] ウィンドウの [メモリ使用量の概要] テーブルで、割り当て (Diff) または ヒープ サイズ (差分) セルの現在のリンクを選択します。

ネイティブ 型ビューのスクリーンショット。

ネイティブ 型ビューのスクリーンショット。

タイプ ビュー には、スナップショット内の型の数とサイズが表示されます。

  • 選択した種類の横にある [インスタンスの表示] アイコンを選択すると、スナップショット内の選択した種類のオブジェクトに関する情報が表示されます。

    インスタンス ビューには、選択した種類の各インスタンスが表示されます。 インスタンスを選択すると、割り当て呼び出し履歴 ペインにインスタンスが作成された呼び出し履歴が表示されます。 (この情報は、デバッグ中にのみ使用できます)。

    インスタンス ビューと割り当て呼び出し履歴ペインのスクリーンショット。

  • スナップショットで選択した種類のオブジェクトに関する情報を表示するには、選択した種類のインスタンス アイコン (オブジェクトの種類列のインスタンス アイコン) を選択します。

    インスタンス ビューには、選択した種類の各インスタンスが表示されます。 インスタンスを選択すると、割り当て呼び出し履歴 ペインにインスタンスが作成された呼び出し履歴が表示されます。

    インスタンス ビューと割り当て呼び出し履歴ペインのスクリーンショット。

  • [スタック] を選択すると、選択した種類の割り当てスタックが表示されます。

    スタック ビューのスクリーンショット。

  • [表示モード] リストで [スタックビュー] を選択すると、選択した種類の割り当てスタックが表示されます。

    スタック ビューのスクリーンショット。

メモリ使用量の分析情報

マネージド メモリの場合、メモリ分析ツールでは、複数の強力な組み込みの自動分析情報も提供されます。 [マネージド型] レポートで [Insights] タブを選択すると、重複する文字列スパース配列イベント ハンドラー リークなどの適用可能な自動分析情報が表示されます。

メモリ使用量ツールの分析情報ビューのスクリーンショット。

重複文字列 セクションには、ヒープに複数回割り当てられる文字列の一覧が表示されます。 さらに、このセクションでは、無駄なメモリの合計(インスタンスの数 - 1)が文字列のサイズの倍であることを示します。

スパース配列の セクションには、ほとんどの要素がゼロで満たされている配列が表示されます。これは、パフォーマンスとメモリ使用量の面では非効率的な可能性があります。 メモリ分析ツールは、これらの配列を自動的に検出し、これらのゼロ値のために無駄になっているメモリの量を示します。

Visual Studio 2022 バージョン 17.9 Preview 1 で使用可能な イベント ハンドラー リーク セクションには、あるオブジェクトが別のオブジェクトのイベントをサブスクライブするときに発生する可能性があるメモリ リークが表示されます。 イベントのパブリッシャーがサブスクライバーより長く存在した場合、サブスクライバーへの他の参照がない場合でもサブスクライバーは存続します。 これにより、メモリ リークが発生し、未使用のメモリが適切に解放されず、時間の経過と同時にアプリケーションで使用されるメモリが増える可能性があります。

特定の型には、保持しているネイティブ メモリのサイズを決定するために読み取ることができるフィールドが存在することがわかっています。 [Insights] タブには、オブジェクト グラフに偽のネイティブ メモリ ノードが表示されます。これは、UI で認識され、サイズと参照グラフが表示されるように、親オブジェクトによって保持されます。

メモリ使用量ツールのネイティブインサイトビューのスクリーンショット。

変更 (差分) レポート

  • [メモリ使用量の概要] ページの [スナップショット] ウィンドウのセルにある変更リンクを選択します。

    セルの [変更の選択] リンクのスクリーンショット。

    セルの [変更の選択] リンクのスクリーンショット。

  • マネージド レポートまたはネイティブ レポートの 比較 一覧でスナップショットを選択します。

    スクリーンショット: [比較対象] リストからスナップショットを選択する。

    [比較対象] リストからスナップショットを選択するのスクリーンショット。

変更レポートでは、基本スナップショット値と比較スナップショットの違いを示す列 ((Diff)でマーク) がベース レポートに追加されます。 ネイティブ型ビューの差分レポートの外観を次に示します。

ネイティブ型の差分ビューのスクリーンショット。

ネイティブ型の差分ビューのスクリーンショット。

上部のウィンドウには、スナップショット内の型の数とサイズ (型によって参照されるすべてのオブジェクトのサイズを含む) が表示されます (包括サイズ)。