何千行もの .NET コードを記述するときに、メモリ リークを避けるために何を心に留めていますか? 私は検査よりも予防の大ファンです。この点に関して、「String1+String2」の代わりに「StringBuilder」を使用して文字列を結合する有名な例がありますが、あなたのコーディング経験から他に何がありますか?
あなたの考えを共有してくれてありがとう。
何千行もの .NET コードを記述するときに、メモリ リークを避けるために何を心に留めていますか? 私は検査よりも予防の大ファンです。この点に関して、「String1+String2」の代わりに「StringBuilder」を使用して文字列を結合する有名な例がありますが、あなたのコーディング経験から他に何がありますか?
あなたの考えを共有してくれてありがとう。
イベント。常にイベントのサブスクライブを解除します。これは、.NET の最もリークを引き起こす機能の 1 つです。
イベントにサブスクライブするということは、「私が生きている間に通知して」ではなく、「あなたが生きている間に私に通知して保持する」ことを意味します。イベントのサブスクライブ解除に失敗すると、通常、特に UI で、ぶら下がっているオブジェクトの大規模なクラスターが発生します。
使用後にルート参照を null に設定します。
詳細はこちら: ルート化された参照を null にするのを忘れた場合、GC はメモリをできるだけ早く効率的に解放できなくなり、アプリケーションのメモリ フットプリントが大きくなります。データベース クエリや Web サービスへの呼び出しなどのリモート呼び出しを行う前に、一時オブジェクトの大きなグラフを作成するメソッドなど、問題が微妙な場合があります。リモート呼び出し中にガベージ コレクションが発生すると、グラフ全体が到達可能とマークされ、収集されません。コレクションを生き残ったオブジェクトが次世代に昇格し、中年の危機につながる可能性があるため、これはさらにコストがかかります。
IDisposable オブジェクトは必ず破棄してください。さらに、「using (...)」ブロックを常に使用して、使い捨てオブジェクトを宣言するようにしてください。
自分が行うすべてのことの複雑さを可能な限り認識し、ドグマに頼るのではなく、それぞれの状況について考えてください。たとえば、 StringBuilder を使用することが常に文字列を結合する正しい方法であるとは限らないことにも注意してください:)
可能な場合は、データをバッファリングするのではなく、ストリーミングするようにしてください。LINQ to Objects に関しては、どの演算子がバッファリングし、どのストリームを実行するか (そしてどちらが異なるシーケンスで両方を実行するか) を理解する必要があります。
(どちらも実際にはメモリ「リーク」ではありませんが、予想よりも多くのメモリを急速に使用できる場所について考えています。)
すべての DataTable.NewRow() には、一致する DaraTable.Rows.Add(...) が必要です。
正確にはメモリリークではありませんが、常に私を悩ませていることの1つは次のとおりです。
使用後は常にSQL 接続を閉じてください。
something.someEvent += new EventHandler(memoryhog.someMethod);
[...]
something.someEvent += new EventHandler(memoryhog.someMethod);
[...]
something.someEvent -= new EventHandler(memoryhog.someMethod);
オブジェクトからすべてのイベント ハンドラーをアンフックし損ねた場合、イベント ハンドラーを実装するオブジェクトは、イベントが発生したオブジェクトの存続期間中、メモリ内に残ります。
Managed DirectX ライブラリには、このようなバグがあり、大量のメモリ リークが発生していました。
COM 相互運用機能を使用している場合は、COM オブジェクトの処理が完了した後で Marshal.ReleaseComObject を使用して、ランタイム呼び出し可能ラッパー (RCW) を解放します。
また、COM オブジェクトに別の COM オブジェクトを返すプロパティまたはメソッドがある場合は、常に変数に割り当てて後で解放するように注意してください。
つまり、これは GetFirstChild によって受信されたオブジェクトをリークします。
string name = myBigComObject.GetFirstChild().Name;
代わりに使用:
ChildComObject firstChild = myBigComObject.GetFirstChild()
string name = firstChild.Name;
Marshal.ReleaseComObject(firstChild);
.NET Compact Frameworkに固有: すべてのグラフィックス関連オブジェクト (Graphics、Pen、SolidBrush、Bitmap) を明示的に破棄する必要があります。そうしないと、オブジェクトがメモリ内にぶら下がってしまいます (メモリの少ないデバイスで作業している場合には適していません)。