4

かなり長い間、アプリケーションのメモリ リークを修正しようとしてきました。数か月前、私のアプリケーションでは、オブジェクトの 95% 以上が Gen2 に昇格されていることに気付きました。また、本では見つけることができなかった非常に基本的な質問がいくつかあります。皆さんが私を助けてくれることを願っています:

  1. Gen2 オブジェクトが非常に多いことは悪いニュースですか? スナップショットを作成するたびに、約 77,000 の Gen2 オブジェクト、100 の Gen1 オブジェクト、および 10 の Gen0 オブジェクトを WinDbg で取得します。
  2. 非常に多くのオブジェクトがプロモートされている理由を見つけるにはどうすればよいですか? 良いツールはありますか?私は主にWinDbg/SOSを使用してきましたが、あまり運がありませんでした

前もって感謝します。

4

1 に答える 1

14

Gen2 オブジェクトが非常に多いことは悪いニュースですか?

これは悪いニュースではありません。GC.Collect が実行されたばかりか、かなり頻繁に実行され、十分な空きメモリがあることを意味している可能性があります。したがって、Gen2 のオブジェクトは収集されません。別の StackOverflow の質問からの良い説明を次に示し ます。必要な場合でもガベージ コレクションは発生しません

ガベージ コレクションを開始すると、GC は収集する必要がある世代 (0、0+1、またはすべて) を決定します。各世代には、GC によって決定されるサイズがあります (アプリケーションの実行時に変更される可能性があります)。ジェネレーション 0 だけが予算を超える場合、ガベージが収集されるのはそのジェネレーションのみです。ジェネレーション 0 を生き残ったオブジェクトが原因でジェネレーション 1 が予算を超えた場合、ジェネレーション 1 も収集され、その生き残ったオブジェクトはジェネレーション 2 (Microsoft の実装では最高のジェネレーション) に昇格されます。ジェネレーション 2 の予算も超えた場合、ガベージは収集されますが、オブジェクトが存在しないため、より高いジェネレーションに昇格することはできません。

したがって、ここに重要な情報があります。GC が開始される最も一般的な方法では、ジェネレーション 0 とジェネレーション 1 の両方がいっぱいの場合にのみジェネレーション 2 が収集されます。また、85,000 バイトを超えるオブジェクトは、ジェネレーション 0、1、および 2 の通常の GC ヒープには格納されないことを知っておく必要があります。実際には、ラージ オブジェクト ヒープ (LOH) と呼ばれるものに格納されます。LOH 内のメモリは、FULL コレクション中 (つまり、ジェネレーション 2 が収集されるとき) にのみ解放されます。ジェネレーション 0 または 1 のみが収集されている場合は never。

2 番目の質問に:

非常に多くのオブジェクトがプロモートされている理由を見つけるにはどうすればよいですか? 良いツールはありますか?私は主にWinDbg/SOSを使用してきましたが、あまり運がありませんでした

Windbg と SOS は良いです :) この状況では、psscor2 (.NET 4.0 を使用している場合は psscor4) を追加することをお勧めします。特定の世代のオブジェクトを簡単にダンプするには、psscor を使用する必要があります。

psscor2およびpsscor4 dllをダウンロードするための公式リンクは次のとおりです。それらの適切なバージョンを Windbg がインストールされているフォルダーに配置します。x86 バージョンの dll は x86 フォルダー (C:\Program Files (x86)\Debugging Tools for Windows) に、x64 バージョンの dll は x64 フォルダー (C:\Program Files\Debugging Tools for Windows (x64)) に移動します。

その後、次のコマンドを実行できます。

    !dumpheap -gen 2

psscor のように、SOS には特定の世代のオブジェクトのみをダンプする簡単なコマンドがありません。

このコマンドを使用すると、次のような構造を作成できます。

.foreach (obj { !dumpheap -gen 2 -short }) { !do ${obj} }

また

.foreach (obj { !dumpheap -gen 2 -type ExactTypeName -short }) { !gcroot ${obj} }

gen 2 のオブジェクトの主なタイプと、それらを参照するメソッドを見つける。

あなたが言ったように、あなたの主なアイデアはメモリリークを見つけることです。より一般的なアプローチを使用し、世代だけでなく分析する必要があります。メモリ使用量が多い問題の分析に関する私の投稿は次のとおりです。

管理されたメモリ:

http://kate-butenko.blogspot.com/2012/06/investigating-memory-issues-high-memory.html

アンマネージ メモリ:

http://kate-butenko.blogspot.com/2012/07/investigating-issues-with-unmanaged.html

http://www.codeproject.com/Articles/31382/Memory-Leak-Detection-Using-Windbg

まだいくつかのステップで立ち往生している場合は、質問を残してください。

于 2012-08-10T14:09:44.987 に答える