メモリ使用量に対する参照セットとシステム全体に対する影響
参照セットは、システム全体のメモリ可用性に対するプロセスの実際の影響を理解するために推奨される方法です。
従来、メモリ使用量は特定の時点でのプロセスのワーキング セットによって測定されています。 プロセスのワーキング セットとは、現在は物理メモリに常駐しているプロセスの仮想アドレス空間内の一連のページです (ワーキング セットの詳細については、Windows デベロッパー センターの「ワーキング セット」を参照してください)。
ワーキング セットの制限事項
ワーキング セットで提供される情報は限定されています。これは、キャッシュされたファイルや、プロセスが使用するシステム サービスによって使用されるメモリなど、プロセスをサポートするために使用されるメモリの一部が表示されないためです。 さらに、ワーキング セットは、マシンの状態、RAM の量、要求するメモリをシステム上のすべてのプロセスに提供するためにメモリ サブシステムで必要なアクティビティのレベル (メモリ負荷のレベル) によって大きな影響を受けます。 また、ワーキング セットは、OS のトリミング ポリシーによっても多大な影響を受けます。 そのため、ワーキング セットは一時的な測定のみであり、対象となるプロセス以外の影響は省略されます。
参照セットの利点
これに対し、参照セットは、システム上のプロセスまたはアクティビティが特定のシナリオでアクセスしたシステム全体のメモリ ページのセットを測定したものです。 これには、ページにアクセスしたプロセスに関係なく、調査中のコンポーネントに代わってアクセスされたすべてのページが含まれます。 参照セットは、RAM のサイズ、メモリの負荷、または OS のトリミング ポリシーによって変わることはありません。 参照セットの測定は、すべてのワークロードについてシステム全体のメモリ使用量を評価する非常に正確な方法です。これは、現在プロセスのワーキング セット内にあるページ、またはシステム プロセスまたはドライバーによってアクセスされているページが参照セットに含まれているためです。 参照セットは特定の時点ではなく、シナリオに固有のものです。つまり、「この時点のプロセスの参照セットはどういうものか」と考えるのは間違っています。そうではなく、「このシナリオでのシステムの参照セットはどういうものか」または「このシナリオでのプロセスの参照セットはどういうものか」と考えるのが適切です。
参照セットの背後にある考え方は単純です。シナリオ中にシステム全体で参照されるメモリを正確に把握するために、アクセス時と解放時にページがカウントされます。 このメソッドは、メモリ使用のピークを包括的に確認できるだけでなく、シナリオの最後に未処理のデータ (つまり、安定した状態の使用を提供します)。
注意
ページの最初の参照のみがキャプチャされます。
大まかに言うと、参照セットは、シナリオの実行中にシステムの残りの部分から取り出される可能性のあるメモリの量の測定値、または同様に、シナリオを実行するためにディスクから探して読み取る必要があるメモリの量 (システムの他の部分によってメモリがページアウトされた場合) と見なすことができます。 このため、参照セットはメモリ使用量のパフォーマンス上の影響を判別する際に役立ちます。
参照セット データの収集方法
2 つの異なるコマンド ライン ツール、Windows Performance Recorder (WPR) と Xperf を使用して、参照セット データを収集できます。 WPR の GUI インターフェイスを使用することもできます。
WPR と Xperf は、Windows Assessment and Deployment Kit (ADK) に含まれる Windows Performance Tookit の一部です。 ADK for Windows 10は、次のリンクからダウンロードできます。Windows Assessment and Deployment Kit。
注意
参照セット データを収集するときは、管理者特権のコマンド プロンプトを使用します。
WPR を使用したデータの収集
WPR を使用してデータを収集するには、次のコマンドを入力します。
wpr -start referenceset -filemode
シナリオを実行し、次を入力してデータの収集を停止します。
wpr -stopfile-name.etl
Xperf を使用したデータの収集
Xperf を使用してメモリ トレースを収集する場合は、最小バッファーと最大バッファーの両方に同じサイズを指定して、Event Tracing for Windows (ETW) に予約されるシステム メモリの量が一貫して確保されるようにします。 この一貫性により、変動が減り、実行間の比較が容易になります (WPR を使用すると、これらのバッファーは自動的に同じサイズに設定されます)。
Xperf を使用してデータを収集するには、次のコマンドを入力します。
xperf -on referenceset -minbuffers 50 -maxbuffers 50 -buffersize 1024 -stackwalk PageAccess+PageRelease+PageRangeAccess+PageRangeRelease+PagefileMappedSectionCreate+VirtualFree+PagefileMappedSectionDelete -start user -on Win32HeapRanges -minbuffers 10 -maxbuffers 10 -buffersize 1024
シナリオを実行し、次を入力してデータの収集を停止します。
xperf -stop user -stop -dfile-name.etl
WPR デスクトップ アプリを使用したデータの収集
WPR デスクトップ アプリ wprui.exe を使用してデータを収集することもできます。 GUI の [リソース分析] で [Reference Set analysis (参照セットの分析)] を選択します。 (このオプションが表示されないときは、[その他のオプション] をクリックし、[Resource Analysis (リソース分析)] を展開する必要がある場合があります)。
記録を開始するには、[開始] をクリックして、シナリオを実行します。
記録を停止し、トレース データを保存するには、[保存] をクリックします。
参照セットのトレースのしくみ
WPR が参照セットのトレースの収集を開始すると、システムは、システムを含むすべてのプロセスのワーキング セットからすべてのメモリ ページを直ちに削除します。 さらに、プロセスまたはシステムのワーキング セットに残っているすべてのページは、ロックまたは非ページ可能としてマークされているページを考慮して記録されます。 その後、スタンバイ リストに移動されたページの最初のアクセス時に、システムは参照セットのトレースにソフト エラーを記録し、そのページをプロセスのワーキング セットに追加して、プロセスの実行を続行します。 その後、プロセスまたはシステムのワーキング セット内のページにアクセスしても、そのページは既にワーキング セット内にあるため、さらにソフト ページ エラーが発生することはありません。 その結果、実行はワーキング セット内のページへの追加のアクセスを記録せずに続行されるため、ページへのアクセスの総数はトレースに記録されません。
同様に、同じプロセス内の他のページの最初のアクセスは、新しく割り当てられたページを含め、トレースに記録されます。 解放されたページ (HeapFree によって解放されたページなど) と削除されたページは、測定間隔の最後に参照セットから未処理のサイズが削除されますが、引き続きアクセス済みとして表示されます。 閉じているファイル、またはメモリから削除された実行可能ファイルは、閉じられたときや削除されたときに RAM から消去されないため、未処理のサイズから削除されません。 ページが 2 つ以上のプロセス間で共有されている場合、トレースでは、そのページにアクセスする各プロセスで、そのページへの最初のアクセスが記録されます。
注意
参照セットのトレースを記録すると、システムのパフォーマンスに大きな影響を与える可能性があります。すべてのプロセスでは、ワーキング セットが空になった後に、多数のページがワーキング セットに障害を発生させる必要があるためです。
参照セットの視覚化
WPA では、参照セット データの次のビューが提供されます。
参照セットのプロセス別の未処理サイズ
これにより、ビューポートのプロセスで割ったメモリが表示されます。 これは、特定のアプリケーションのメモリへの影響を調査する場合に開始する最適な場所です。
このビューの列の意味については、このトピックの後半にある「重要な列定義」を参照してください。
参照セットのカテゴリ別の未処理サイズ
これにより、ビューポートのメモリ ページがカテゴリ別に表示されます。
ページ カテゴリの詳細については、このトピックの後半にある「ページ カテゴリ (動的)」と「ページ カテゴリ (ファイル)」を参照してください。
参照セットの動的/ファイル別の未処理サイズ
これにより、ビューポートに対してメモリとファイルのどちらを使用するかによって分類されてメモリが表示されます。
注意
メモリベースのページ は、ページ ファイルによってサポートされます。ページ プール以外の場合は、ページアウトされません。メモリベースのページには、スタック、ヒープ、VirtualAlloc、ディスク上のファイルに直接マップされないその他のページ カテゴリが含まれます。 ファイルを使用するページは、モジュール イメージなどのディスク上の個々のファイルによってサポートされます。
参照セット データについて
前述のように、参照セットは、関心のあるシナリオの実行中に触れたメモリを表します。 この点に関して、参照セットはワークロードを実行する実際のコストであり、ワークロードのメモリフットプリントの最も正確な計算を表します。
通常、特定のプロセスのメモリ フットプリントに関心を持つため、[プロセス別に未処理の参照セット] 表で開始します。 メモリ使用量が増加または減少した場所と、ピーク時の場所と安定した場所を調べる必要があります。
ピークと安定状態
参照セットはシナリオ中に参照されるメモリ量の測定値であるため、そのサイズが減少する可能性があることは直感的に理解できない可能性があります。 メモリが解放され、他の目的で使用するためにシステムに返された場合、そのメモリは参照セットから減算され、後で再利用できるという事実が反映されます。
これにより、1 つのシナリオに安定状態とピークという 2 つの主要な参照セット メトリックが含まれるようになります。
メトリック | 説明 |
---|---|
安定 状態 | アプリまたはシナリオのベースライン コスト。 これは、シナリオ (または複数のシナリオ) を実行し、システムがアイドル状態に再び到達するまで待機することで測定できます。 さまざまなシナリオでアプリが安定した状態でアクセスするページの数を最小限に抑えることにより、システム上のメモリへの負荷を減らすことで、シナリオの実行速度を向上し (より迅速に再開するなど)、ユーザーにとってより優れたエクスペリエンスを提供できます。 |
Peak | メモリの使用量が一時的に高い状態であり、物理メモリからより重要な情報がプッシュされる可能性があります。 使用量のピークの頻度と大きさを削減し、他のプロセスのスワップ アウトや終了の可能性を低減すると、アプリや機能はより優れた「システム シチズン」になります。 |
重要な列定義
WPA で参照セットのトレースを調べるときは、テーブル ビューの次の列が特に重要です。
これらの列のいずれかが WPA のビューに表示されない場合は、現在のビューの列見出しを右クリックし、欠落している列を一覧から選択して追加できます。
3 つのすべての参照セットビューには、カウントされるメモリのサイズを示す 4 つの異なる列があります。
- [サイズ (プロセス ビュー)]: 指定されたプロセスによって参照されるページの合計セット
- [Size (System View) (サイズ (システム ビュー))]: 参照されるページのセット
- [影響サイズ (プロセス ビュー)]
- [影響サイズ (システム ビュー)]
既定では、ビューごとに表示される列は異なりますが、それらを検索すると、すべての参照セット ビューで使用できるようになり、使用するビューに関係なく同じ方法でサイズが追加されます。
[影響の種類]
[影響の種類] 列は、現在使用されているメモリにメモリ割り当てが及ぼす影響の種類 ([Impacting (影響を与える)]、[一時的]、および [永続的]) を示します。
影響の種類 | 説明 |
---|---|
Impacting (影響を与える) | ビューポートの開始前に割り当てられ、ビューポートの間に解放されたメモリ (A)、またはビューポートの間に割り当てられ、ビューポートの終了後に解放されたメモリ (内部で割り当てられ、外部で解放される)。 影響を与える割り当ては、ビューポートの終了時に使用されているメモリに影響を及ぼします。 |
一時的 | ビューポートの間に割り当てられて、解放されたメモリ (内部で割り当てられ、内部で解放される)。 一時的な割り当ては、現在のビューポート内でのみアクティブです。 通常、一時的な割り当ては、ビューポート内の使用量のあらゆるピークに影響を及ぼします。 |
永続的 | ビューポートの開始前に割り当てられ、ビューポートの終了後に解放された割り当て (外部で割り当てられ、外部で解放される)。 永続的な割り当ては、ビューポート全体でアクティブになります。 |
サイズと影響サイズ
[Reference Set Outstanding by Process (参照セットのプロセス別の未処理)] の [サイズ] 列には、割り当てによって生じる影響の種類 ([影響の種類] 列に [Impacting (影響を与える)]、[一時的]、または [永続的] のいずれかとして表示される) によって左右されないアクセスの大きさが示されます。 これは分析にはあまり役立ちませんが、WPA でのグラフ化に必要です。
[影響サイズ] は、タイムスタンプから現在のズームレベルの終了タイムスタンプまでのサイズに対する影響を表します。 ビューのフィールドの先頭と末尾にあるグラフ化された値の比較は、簡単に言うと、デルタに相当します。 一時的または永続的なアクセスによって、グラフの値がズーム ウィンドウに応じて変更されることはないため、カウントされません。
2つのプロセスが物理メモリの同じページを参照している場合、ページは [サイズ] 列の各プロセスに対してカウントされます。 2 つの値を追加しても、参照セットのシステム全体の合計は生成されません。これは、ページがワーキング セットに追加された後、その後のアクセスがカウントされないためです。 また、ページは [影響サイズ] 列で、ページにアクセスする最初のプロセスに対して 1 回のみカウントされます。 プロセスの [影響サイズ] に値を追加すると、参照セットの有効なシステム全体の合計が生成されます。これは、ページの数に欠落または乗算を生じることなく実行されます。 このため、[影響サイズ] の値はメモリに対する実際のシステム全体の影響を表します。
次の値を使用して、t_start から t_end までの例を考えてみましょう。
t_start でのグラフ: 10 MB
ウィンドウ内の新しい (Impacting (影響を与える)) アクセス: 10 MB
ウィンドウ内の一時的なアクセス: 10 MB
t_end でのグラフ: 10 (永続的) + 10 (Impacting (影響を与える)) = 20
[サイズ] 列: 10 (永続的) + 10 (一時的) + 10 (Impacting (影響を与える)) = 30
[影響サイズ] 列: 10 (Impacting (影響を与える))
注意
拡大/縮小するとビューポートが変更され、これらのサイズが再計算されます。
Category クラス
メモリ ページへのアクセスには 2 つのカテゴリがあり、WPA では、[Category クラス] 列で [動的] または [ファイル] として識別されています。
Category クラス | 説明 |
---|---|
動的 | これらは、システムのシャットダウンの後に保持されないプロセスまたはシステム状態に関連付けられているメモリの要求時割り当てです。 割り当ては、非ページにすることも、ページ ファイルでサポートすることもでき、[ページ カテゴリ] 列で識別されるように、[Heap]、[VirtualAlloc] にすることができます。 共有可能な動的メモリも [ページ カテゴリ] で [PFMappedSection] として識別されます。 |
ファイル | これらは、ディスク上のファイルによってサポートされる処理によって参照されるファイルです。 データとして読み込まれたファイル、イメージ (実行可能ファイルまたは DLL) として読み込まれたファイル、およびマップ ファイルです。 |
ページ カテゴリ (動的)
[ページ カテゴリ] 列でカテゴリ クラスが [動的] の場合、次の表に示されているように WPA には 1 つ以上のカテゴリが表示されます。
ページ カテゴリ、動的割り当て | 説明 |
---|---|
VirtualAlloc | このページ カテゴリには、仮想割り当て API を使用してアプリによって作成された (またはアプリの代わりにフレームワークによって作成された) 動的な割り当て (システムによっては、512 KB または 1 MB を超える) が含まれます。 |
ヒープ | このページ カテゴリには、ヒープ割り当て API を使用して、アプリによって作成された (またはアプリの代わりにフレームワークによって作成された) 小規模な動的割り当てが含まれます。 |
UserStack | スレッドのユーザー モード スタック。 |
PFMappedSection | 共有可能な動的メモリ。 このページ カテゴリは、多くの場合、グラフィックス割り当てで消費されるメモリの量を測定します。 アプリの観点から見ると、これには、イメージ、ビデオ、アプリが使用している他の「メディア パイプライン」の割り当てだけでなく、ListView のレンダリングに使用されるサーフェイスなどの UI の基本的な構成要素も含まれます。 |
CopyOnWriteImage | プロセスに読み込まれたモジュールの書き込み時コピー ページ。 |
LargePage | |
AWEPage | プロセスによって割り当てられた物理ページ。 |
PageTable | |
PagedPool | カーネルヒープ。 |
Non-PagedPool | ページング不可能なカーネル ヒープ。 |
SessionPrivate | |
KernelStack | カーネル モード スタック。 |
Driver | |
DriverLockedSystemPage | |
System PTEs |
ページ カテゴリ (ファイル)
[ページ カテゴリ] 列でカテゴリ クラスが [ファイル] の場合、次の表に示されているように WPA には 1 つ以上のカテゴリが表示されます。
ページ カテゴリ、ファイル | 説明 |
---|---|
Image | DLL などの実行可能ファイルとして読み込まれるファイル。 |
MapFile | データとして読み込まれるファイル。 |
MetaFile | ディレクトリまたはシステム ログ。 |
RegistryFile | レジストリ ファイル。 |
Prefetcher | アプリの起動を高速化するために使用される情報。 |
DriverFile | 実行可能ファイルとして読み込まれるドライバー。 |
割り当て履歴
[割り当て履歴] 列は、メモリが割り当てられる場所を識別します。
影響を与えるスタック
[影響を与えるスタック] 列には、メモリがアクセスされた理由が示されます。
参照セットのパフォーマンスを測定および改善するための推奨事項
次の一般的な推奨事項は、参照セットを測定し、システム上のアプリまたは機能の効果を向上させるのに役立ちます。 これらの推奨事項は、次の順序で使用します。
メモ トレースではメモリが使用されます。これは、 ETW バッファーの説明 "ETWB" を含む非ページ プールとして表示されます。
メモリの安定状態の使用とピーク時の使用を調べる
シナリオの最後に安定した状態にあるメモリ使用量、および参照セットで使用量のピークが発生する場所と理由という 2 つの側面が重要です。 分析では、まずシナリオの安定状態の影響に焦点を当て、次に参照セットのグラフ内の特定のピークを確認する必要があります。
最大の効果を持つプロセスに焦点を当てる
関心のあるプロセスや他のシステム プロセスなど、参照セットに最も大きな影響を与えるプロセスに焦点を当てます。
メモリ ページの特徴付けと分類を行う
メモリ ページのカテゴリ クラス、動的クラスとファイル クラスの両方に対して特徴付けを行い、さらにサブカテゴリに分割する必要があります。
ファイル カテゴリのメモリ ページを調べる
ファイル アクセスを調べる最善の方法は、通常、パス ツリーでグループ化し、システム関連のファイル アクセス (DLL など) とプロセス固有のファイル アクセス (ローカル データベース、テキスト ファイル、JPEG など) を識別することです。
プロセス固有のファイル アクセスを最小限に抑えると、参照セットのサイズが小さくなります。 また、テストするアプリケーションまたは機能が読み込まれる前に、テストを開始するパフォーマンスも高まります (コールド シナリオ)。
基本的に、参照セットのファイル部分を診断するには、シナリオに固有の DLL と読み込まれる理由、およびアプリケーションまたは機能がアクセスするファイル (スライドショーのデコード時のイメージ ファイルなど) を把握しておく必要があります。
動的カテゴリのメモリ ページを調べる
参照セットのトレースを分析するには、次の順序で行います。
ページ カテゴリ別に分類する
ページ カテゴリ別に、Win32Heap、VirtualAlloc、または PFMappedSection に分類します。 カテゴリは、プロセスに直接属性として指定できます。
通常、システム固有のカテゴリは初期分析では無視できます。ただし、通常、ページプールまたはカーネル スタックからの大きな貢献 (2 から 3 MB を超える) があるときは、多くの場合、レジストリなどのスレッドやコンポーネントの過剰使用を示すため、調査する価値があります。
スタック タグを適用する
スタック タグを適用してスタック別にメモリ使用量を分類すると、メモリ使用量の発生場所を特定するのに非常に役立ちます。
ヒープ固有のトレースを実行する
参照セットのスタック タグを使用すると、ヒープを使用しているプロセスの一般的な概念を得られますが、多くの場合、ヒープの使用状況がシナリオに大きな影響を与えるときは、ヒープ固有のトレースを実行する必要があります。 参照セットでは参照されるメモリ ページのみが識別されるため、割り当ての観点からヒープを分析するために必要な詳細度は得られません。 ヒープの割り当て自体が小さく、ヒープ全体に分散している場合でも、ヒープの使用量が大きく断片化したヒープでは、大きな安定した状態のフットプリントが表示される場合があります。
使用率が高い割り当てスタックを調べる
VirtualAlloc: VirtualAlloc の使用率が高い特定の割り当てスタックを調べます。 [分析] タブで [VirtualAlloc Commit LifeTimes (VirtualAlloc コミットの有効期間)] を表示すると、プロセス別のコミット使用状況の詳細が表示されます。
大きな影響を与えるシステム プロセスを調べる
このシナリオの結果としてメモリに大きな影響を与える他のシステム プロセスはありますか? 候補の例としては、サービス、アプリ ブローカー、ウイルス対策スキャナーがあります。
コストを分析し、削減するための選択肢を特定するために分類する
前の推奨事項に従った後、次の手順を使用して、システムに最も大きな影響を与えるスタックを分析し、メモリ コストを削減する方法を調べます。
コストが最も高いスタックを特定します。
各スタックが行うであろう名前で注釈を付けて、スタックを分類します。
各カテゴリとスタックのコストが、シナリオに対して予想される量であるかどうかを検討します。
必要な場合にのみメモリを割り当てるなどして、アクティブなシナリオでピークを減らすことができるかどうかを検討します。
メモリの安定した状態の使用量を削減できるかどうかを検討します。 たとえば、シナリオ固有で不要な安定状態の間にリソースを解放できますか? たとえば、キャッシュやプールされたリソースなどです。 リソースを解放すると、安定状態のメモリ フットプリントが減少する可能性があります。