4

パターンを議論するガイド/ノート/記事のいずれも、メソッドでIDisposable内部メンバーを設定する必要があることを示唆していません(特に、それらがメモリを大量に消費する獣である場合)。nullDispose(bool)

内部のベンチマーク ツールをデバッグしているときに、その重要性に気づきました。以前は、内部に大きな配列を含むこのバッファがありました。以前は、ベンチマーク プログラム全体に静的バッファを使用していました。バッファーの処理が完了すると、この内部配列を解放する方法はなく、このバッファーを解放可能にすることもできません (静的であるため)。

したがって、Dispose()が呼び出された後、破棄されるオブジェクト自体がGCによって回収されず、設定されていなくても、使用しているすべてのリソースを解放して再び利用できるようにするために、クラスはできる限りのことを行う必要があると思いますメンバーを null にすることで、GC による内部オブジェクトの収集を許可しないということは、Dispose の実装が完全ではないことを意味します。

これについてどう思いますか。

4

3 に答える 3

6

実行中に追加の参照を解放するDisposeことは、次の 2 つの理由から、私がやろうとしていることです。

  • 破棄されたオブジェクトがまだスコープ内にある場合でも、内部オブジェクトをガベージ コレクションできます。
  • Dispose()内側のオブジェクトが破棄可能である場合、外側のオブジェクトで繰り返し呼び出されたとしても、一度だけ破棄することを意味します

たとえば、私は次のようなものを使用する傾向があります。

if(someDisposableObject != null)
{
    someDisposableObject.Dispose();
    someDisposableObject = null;
}
(for non-disposable, just set to null)
someNonDisposableObject = null; // etc

イベントを null に設定することもできます。

someEventHandler = null;

これにより、呼び出し元が現時点で参照を完全に解放できない (または単に忘れた) 場合の影響を最小限に抑えることができます。(GC の場合) 外側のオブジェクトを解放しようとする必要がありますが、たとえば、キャプチャされた変数 (匿名メソッド/ラムダ)、イベントなどを介して、オブジェクトの寿命を誤って延長することは比較的簡単です。

ファイナライザーがある場合、GC プロセス中にこれを行う利点はなく、外部オブジェクトのメソッドを実際に呼び出すべきではありません ( であってもDispose()) - つまり、GC スイープ中にこれを実行しないでください。

于 2009-01-19T05:01:27.810 に答える
1

多分私はあなたの要点を見逃していますが、オブジェクトが破棄されると、それが表すルートまたは「サブルート」は、そのメンバーに関連して切り離されます。参照カウントシステムのようなガベージコレクションを考えているようです(これは可能ですが、通常はそうではありません)。

代わりに、すべてのオブジェクトがリンク先のブランチを持つ多根ツリーと考えてください。結局のところ、「最終ルート」は静的であり、「メイン」ループからインスタンス化されたものです。

ガベージ コレクターが実行されるとき、それが何をするかを考える最も簡単な方法は、それが「実際のルート」のリストをたどり、「到達」できるすべてのものに「色」を適用することを考慮することです。

ここで、ルート化されているかどうかに関係なく、コレクターが「すべて」にアクセスできると仮定します。着色されていないものはすべてクリーンアップできます。

元の質問に戻ると、オブジェクトが破棄されると、誰もそれを参照しないと想定されます (または少なくとも期待されます)。この場合、root 化されていないため、触れたものの「色付け」には寄与しません。

長い話-Disposeルーチンでメンバーを無効にすることで何かが修正される場合-誰かが破棄されたオブジェクトへのリンクを保持していて、そうすべきではないときに「到達可能」に保つという、別の実際の問題があると思います.

私がこれまでに書いたメッセージの中で最も引用が多すぎるかもしれないことをお詫びしますが、私は標準的な用語を乱用しています.

于 2009-01-19T04:59:45.893 に答える
0

まあ、一般的には、違いはありません。違いが生じる唯一の場所は、Large Object Heap 上のオブジェクトへの参照がある場合です (その動作については既に説明しました)。

これについて詳しく説明している LOH に関する優れた記事があります。

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

于 2009-01-19T04:56:43.967 に答える