2

私は実装しましたDispose...それをサポートするすべての場所。すべてのイベント ハンドラーを削除しています。私はネイティブコードを呼び出していません。

すべての辞書を繰り返し処理し、値を null に設定して、すべての項目で .Clear() を呼び出します。

質問:

コードがリークしている場所を特定するにはどうすればよいですか?

一晩中テストを実行して、最初にリークを発見しました。一定量のメモリを使用するため、成長してからやや静的になります。次に、フォアグラウンド スレッド ディスプレイ メモリを次のように作成しました。

            if (key.KeyChar == 'g')
             {
                long pre = GC.GetTotalMemory(false);
                long post = GC.GetTotalMemory(true);
                Console.WriteLine("{2} Pre:{0}  \tPost:{1}", pre, post, System.DateTime.Now);
                 GC.Collect();
              }

これを数回 (数時間にわたって、時々「g」を押しながら) 実行したところ、増え続ける数値が表示されました。

4

4 に答える 4

1

必ず使用してください

try
{
}
finally 
{ 
   youDisposableObject.Dispose(); 
} 

また

using (yourDisposableObject) {}

実装したすべてのオブジェクトに「破棄」

一部のオブジェクトに不要なファイナライザーを実装した場合は、それらを削除します。

その後も修正できない場合は、メモリ プロファイラーを使用する必要があります。

于 2012-05-22T22:00:58.653 に答える
1

SOS.dll を使用してそれを行う方法を説明した記事がここにあり、より包括的な記事がここにあります。

使用している Visual Studio のバージョン (Premium または Ultimate) によっては、通常のコード分析ツールを使用して、メモリ リークにつながるコードの問題を見つけることもできます。(詳細はこちら

もちろん、マネージ コードでのメモリ リークは、アンマネージ コードでのメモリ リークとは少し異なります。メモリの割り当てと割り当て解除を明示的に行うアンマネージ コードでは、メモリの割り当て解除に失敗すると、メモリ リークが発生します。

.NET では、メモリ リークは、意図したよりも長くオブジェクトにハングアップすることによって発生します。これは、できるだけusingステートメントを使用するベスト プラクティスに従い、変数のスコープを慎重に計画するだけで、ほとんど回避できます。

于 2012-05-22T22:01:44.660 に答える
1

私の c# アプリケーションで同じ問題が発生し、(実際には試用版の) dotTrace メモリ プロファイラーを使用したところ、非常に役に立ちました。

リークが発生した実際のコード行をローカライズするには、まだ時間がかかりました。したがって、そのツールが犯人をすぐに特定できるとは思わないでください。

于 2012-05-22T22:02:29.570 に答える
1

これを追跡する最善の方法は、メモリ プロファイラを使用することです...選択できるものはたくさんあります。

.NET メモリ プロファイリング ツール

于 2012-05-22T21:54:39.993 に答える