プロセス内のメモリ リークをデバッグするために、perfmon Windows ユーティリティを使用しようとしています。
perfmon では用語を次のように説明しています:
ワーキング セットは、このプロセスのワーキング セットの現在のサイズ (バイト単位) です。ワーキング セットは、プロセス内のスレッドによって最近アクセスされたメモリ ページのセットです。コンピューターの空きメモリがしきい値を超えると、ページは使用されていない場合でもプロセスのワーキング セットに残されます。空きメモリがしきい値を下回ると、ページはワーキング セットから削除されます。必要な場合は、メイン メモリから削除される前に、ワーキング セットにソフト フォールトで戻されます。
仮想バイトは、プロセスが使用している仮想アドレス空間の現在のサイズ (バイト単位) です。仮想アドレス空間の使用は、必ずしもディスクまたはメイン メモリ ページのいずれかの対応する使用を意味するわけではありません。仮想空間は有限であり、プロセスはライブラリをロードする能力を制限することができます。
プライベート バイトは、このプロセスが割り当てた、他のプロセスと共有できないメモリの現在のサイズ (バイト単位) です。
私が抱いている疑問は次のとおりです。
共有ライブラリは含まれておらず、リークが発生した場合はプロセス自体から発生するため、プロセスにリークがあるかどうかを確認するために測定する必要があるのはプライベート バイトですか?
プロセスによって消費されるメモリの合計はいくらですか? 仮想バイトですか、それとも仮想バイトとワーキング セットの合計ですか?
プライベート バイト、ワーキング セット、仮想バイトの間には関係がありますか?
メモリ使用量をより正確に把握できる他のツールはありますか?
ベストアンサー1
この質問に対する簡単な答えは、これらの値はいずれも実行可能ファイルが実際に使用しているメモリの量を示す信頼できる指標ではなく、メモリ リークのデバッグに実際に適していないということです。
プライベート バイトは、プロセス実行可能ファイルが要求したメモリの量を示します。必ずしも実際に使用している量ではありません。プライベート バイトは (通常は) メモリ マップ ファイル (共有 DLL など) を除外するため、「プライベート」です。ただし、ここに落とし穴があります。プライベート バイトは、必ずしもそれらのファイルによって割り当てられたメモリを除外するわけではありません。プライベート バイトの変更が実行可能ファイル自体によるものか、リンクされたライブラリによるものかを判断する方法はありません。プライベート バイトは、物理メモリだけに限定されるわけではありません。ディスクにページングすることも、スタンバイ ページ リストにページングすることもできます (つまり、使用されていないが、まだページングもされていない)。
ワーキング セットとは、プロセスが使用する物理メモリ (RAM)の合計を指します。ただし、プライベート バイトとは異なり、これにはメモリ マップ ファイルやその他のさまざまなリソースも含まれるため、プライベート バイトよりもさらに不正確な測定値となります。これは、タスク マネージャーの [メモリ使用量] で報告される値と同じで、近年、混乱の種となっています。ワーキング セット内のメモリは、ページ フォールトなしでアドレス指定できるという意味で「物理的」です。ただし、スタンバイ ページ リストも物理的にはメモリ内に存在しますが、ワーキング セットには報告されません。そのため、アプリケーションを最小化すると [メモリ使用量] が突然低下することがあります。
仮想バイトは、プロセス全体が占有する仮想アドレス空間の合計です。これは、メモリ マップ ファイル (共有 DLL) を含むという意味でワーキング セットに似ていますが、スタンバイ リストのデータや、すでにページ アウトされてディスクのどこかのページ ファイルにあるデータも含まれます。負荷の高いシステムで各プロセスが使用する仮想バイトの合計は、マシンが実際に持っているメモリよりも大幅に多くなります。
関係は次のようになります。
- プライベート バイトはアプリが実際に割り当てたものですが、ページファイルの使用量も含まれます。
- ワーキング セットは、非ページ プライベート バイトとメモリ マップ ファイルで構成されます。
- 仮想バイトは、ワーキング セットとページ化されたプライベート バイトおよびスタンバイ リストで構成されます。
ここで別の問題があります。共有ライブラリがアプリケーション モジュール内にメモリを割り当てて、アプリのプライベート バイトで誤検知が報告される可能性があるのと同様に、アプリケーションも共有モジュール内にメモリを割り当てて、誤検知につながる可能性があります。つまり、プライベート バイトにはまったく現れないメモリ リークがアプリケーションで発生する可能性が実際にあるということです。可能性は低いですが、あり得ます。
プライベート バイトは、実行可能ファイルが使用しているメモリ量の適切な近似値であり、メモリ リークの可能性のある候補のリストを絞り込むのに役立ちます。数値が絶えず増え続けている場合は、そのプロセスにリークがないか確認する必要があります。ただし、これでリークがあるかどうかは証明できません。
Windowsでメモリリークを検出/修正する最も効果的なツールの1つは、実際にはビジュアルスタジオ(リンクは製品ページではなく、メモリ リークに対する VS の使用に関するページに移動します)。合理的な浄化もう一つの可能性もある。マイクロソフトには、より一般的なベストプラクティス文書このテーマに関するツールは他にもたくさんあります前の質問。
これでいくつかの疑問が解消されたと思います。メモリ リークの追跡は、デバッグで最も難しい作業の 1 つです。頑張ってください。