27

C# でのメモリ リークの原因を突き止めるためのアドバイスを参考にしてください。メモリ リークとは何か、C# で発生する理由はわかりましたが、過去にどのようなツールや戦略を使用して解決したのでしょうか?

.NET メモリ プロファイラを使用していますが、巨大なメイン​​ オブジェクトの 1 つが、管理するウィンドウを閉じた後もメモリ内に残っていることがわかりましたが、そのオブジェクトへのすべてのリンクを切断する方法がわかりません。

十分に明確でない場合は、質問付きの回答を投稿してください。それに応じて質問を編集します。ありがとう!

4

2 に答える 2

39

デバッガーを中断し、イミディエイト ウィンドウに次のように入力します。

.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll

sos.dll へのパスはさまざまです。正しいパスを見つける方法は、[モジュール] ウィンドウで mscorwks.dll を探すことです。ロード元が sos.dll の正しいパスです。

次に、次のように入力します。

System.GC.Collect()

これにより、到達できないものはすべて確実に収集されます。次に、次のように入力します。

!DumpHeap -type <some-type-name>

これにより、既存のすべてのインスタンスのテーブルがアドレスとともに表示されます。次のように、インスタンスを維持しているものを見つけることができます。

!gcroot <some-address>
于 2008-10-22T23:56:28.063 に答える
8

.NET Memory Profiler は優れたツールであり、WPF アプリケーションのメモリ リークを診断するために頻繁に使用しています。

お気づきだと思いますが、特定の機能を使用する前にスナップショットを作成し、使用後に 2 番目のスナップショットを作成し、ウィンドウを閉じるなどの方法で使用することをお勧めします。2 つのスナップショットを比較すると、次のことができます。割り当てられているが解放されていない特定のタイプのオブジェクトの数を確認します。これはリークです。

タイプをダブルクリックすると、プロファイラーはそのタイプのオブジェクトを維持する最短のルート パスを表示します。.NET オブジェクトが WPF でリークするさまざまな方法があるため、表示されているルート パスを投稿すると、最終的な原因を特定するのに役立ちます。ただし、一般的には、これらのオブジェクトがオブジェクトを保持している理由を理解しようとし、ウィンドウが閉じられたときにイベント ハンドラーやバインディングなどを切り離す方法があるかどうかを確認してください。

私は最近、特定のバインドが原因で発生する可能性のある特定のメモリ リークに関するブログ エントリを投稿しました。その特定のタイプのリークの場合、そこにあるコードは、障害のあるバインディングを見つけるのに役立ちます。

于 2008-10-23T04:54:48.523 に答える