すべてのオブジェクトをに設定する必要がありますnull
(Nothing
VB.NETで)あなたはそれらを終えたら?
.NETでは、それを実装するオブジェクトのインスタンスを破棄することが不可欠であることを私は理解しています。IDisposable
いくつかのリソースを解放するためのインタフェースisDisposed
フォーム内のプロパティ)、だから私はそれがまだメモリに、または少なくとも部分的に常駐できると思いますか?
また、オブジェクトがスコープ外に出ると、ガベージコレクタの次のパスに備えてコレクションの準備ができたことになります(ただし、これには時間がかかります)。
だからこれを念頭に置いてそれをに設定されますnull
それがもはや範囲にないことを解決する必要はなく、それらは何らかの悪い副作用であるのでメモリを解放するシステムをスピードアップするでしょうか?
MSDNの記事では例でこれを行うことは決してなく、現在はできないのでこれを行います。 害を見なさい。しかし、私は意見が混在しているので、コメントは役に立ちます。
Karlは絶対に正しいので、使用後にオブジェクトをnullに設定する必要はありません。オブジェクトが実装している場合IDisposable
、あなたが呼ぶことを確かめなさいIDisposable.Dispose()
そのオブジェクトを使い終わったら(try
..finally
または、using()
ブロック)。あなたが電話することを忘れていなくてもDispose()
オブジェクトのファイナライザメソッドが呼び出すべきですDispose()
あなたのために。
私はこれが良い治療だと思いました:
この
セルフチューニングで不透明なので、GCとその管理戦略を2回目で推測しようとしても意味がありません。 Dot Net Rocksに関するJeffrey Richterとの内部的な働きについては、ここで良い議論がありました。Windowsメモリモデルに関するJeffrey Richterと 裁判官の本C#によるCLR第20章にはすばらしい扱いがあります。
オブジェクトを使い終わったときにオブジェクトをnullに設定しないようにするもう1つの理由は、オブジェクトを実際に長期間使用できるようにするためです。
gt;
void foo()
{
var someType = new SomeType();
someType.DoSomething();
// someType is now eligible for garbage collection
// ... rest of method not using 'someType' ...
}
someTypeによって参照されるオブジェクトが "DoSomething"への呼び出しの後にGCされることを許可します
void foo()
{
var someType = new SomeType();
someType.DoSomething();
// someType is NOT eligible for garbage collection yet
// because that variable is used at the end of the method
// ... rest of method not using 'someType' ...
someType = null;
}
メソッドが終了するまで、オブジェクトを存続させることがあります。のJITは通常代入をnullに最適化しますそのため、コードの両方のビットが同じになります。
GC.KeepAlive(someType);
見るericlippert.com/2013/06/10/construction-destruction - NotMe
いいえオブジェクトをnullにしないでください。あなたはチェックアウトすることができますhttp://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx詳細については、しかし、物事をnullに設定しても何もしません、あなたのコードを汚すことを除いて。
また:
using(SomeObject object = new SomeObject())
{
// do stuff with the object
}
// the object will be disposed of
一般に、使用後にオブジェクトをnullにする必要はありませんが、場合によってはそれが良い習慣だと思います。
オブジェクトがIDisposableを実装し、フィールドに格納されている場合は、破棄されたオブジェクトを使用しないようにするために、それをnullにするのが良いと思います。次のようなバグは辛いことがあります。
this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();
フィールドを破棄した後、そのフィールドをnullにして、そのフィールドが再び使用される行でNullPtrExを取得することをお勧めします。さもなければ、あなたは(DoSomethingが何をするかに正確に依存して)行のいくつかの不可解なバグにぶつかるかもしれません。
.Dispose()
。見つかった場合は、IDisposableを正しく使用していません。使い捨てオブジェクトの唯一の用途は、using-blockの範囲内です。ブロックを使用した後は、にアクセスできない場合もあります。myField
もう。そしてusingブロックの中では、null
必須ではありません、using-blockはあなたに代わってオブジェクトを破棄します。 - Suamere
あなたが必要としているのであれば、あなたのコードは十分にしっかりと構造化されていないのでしょう。null
変数
変数の範囲を制限する方法はいくつかあります。
で述べたようにスティーブ・トランビー
using(SomeObject object = new SomeObject())
{
// do stuff with the object
}
// the object will be disposed of
同様に、あなたは単に波括弧を使うことができます:
{
// Declare the variable and use it
SomeObject object = new SomeObject()
}
// The variable is no longer available
私は、コードを本当に整理して理解しやすくするために、「見出し」を付けずに中括弧を使用することに気付きました。
変数をnullに設定する必要があるのは、変数が範囲外にならず、それに関連付けられたデータが不要になったときだけです。それ以外の場合は必要ありません。
通常はnullに設定する必要はありません。しかし、あなたのクラスにリセット機能があるとします。
Disposeの一部は正しく実装されていない可能性があり、System.ObjectDisposed例外をスローするため、disposeを2回呼び出すことは望ましくないためです。
private void Reset()
{
if(_dataset != null)
{
_dataset.Dispose();
_dataset = null;
}
//..More such member variables like oracle connection etc. _oraConnection
}
このような「使用後にオブジェクトをnullに設定する必要はない」というのは、完全に正確というわけではありません。変数を破棄した後にNULLにする必要がある場合があります。
はい、必ず電話をかけてください.Dispose()
または.Close()
あなたが終わったときにそれを持っているものに。ファイルハンドル、データベース接続、または使い捨てオブジェクトです。
それとは別に、LazyLoadの非常に実用的なパターンがあります。
インスタンス化したとしましょうObjA
のclass A
。Class A
というパブリックプロパティを持っていますPropB
のclass B
。
内部的には、PropB
のプライベート変数を使用します_B
デフォルトはnullです。いつPropB.Get()
使用されているかどうかを確認します_PropB
nullの場合、インスタンス化に必要なリソースを開きます。B
に_PropB
。それから戻る_PropB
。
私の経験では、これは本当に便利なトリックです。
nullにする必要があるのは、何らかの方法でAをリセットまたは変更した場合です。_PropB
の以前の値の子でしたA
、あなたは処分する必要があります_PropB
そのため、LazyLoadは、コードで必要な場合に正しい値を取得するようにリセットできます。
あなたがするだけなら_PropB.Dispose()
そしてLazyLoadのnullチェックが成功すると期待した直後にnullにはならず、古くなったデータを見ることになります。実際には、後にそれを無効にする必要がありますDispose()
念のために。
私はそれがそうでなければいいと確信しています、しかし私はコードを持っています。Dispose()
に_PropB
そして、Disposeを実行した呼び出し関数の外側(したがってほぼ範囲外)では、プライベートプロップはまだnullではなく、古いデータはまだ存在します。
最終的に、処分された財産は無効になりますが、それは私の見解からすると非決定的です。
dbkkが暗示しているように、根本的な理由は、親コンテナ(ObjA
とPropB
)のインスタンスを保持している_PropB
にもかかわらず、Dispose()
。
null参照に意味がある場合がいくつかあります。たとえば、優先順位付きキューなどのコレクションを作成しているときや、契約上、クライアントがキューからそれらを削除した後は、それらのオブジェクトをクライアントから解放しないでください。
しかし、この種のことは長命のコレクションにおいてのみ重要です。キューが作成された関数の終わりを超えてキューが存続しない場合は、それほど重要ではありません。
全体として、あなたは本当に気にするべきではありません。あなたができるように、コンパイラとGCに任せましょう。
この記事も見てください。http://www.codeproject.com/KB/cs/idisposable.aspx
ほとんどの場合、オブジェクトをnullに設定しても効果はありません。あなたが必ずそうするべきである唯一の時はあなたがサイズが84Kより大きい(ラージオブジェクト)(ビットマップのような)である「ラージオブジェクト」を使っているならばです。
GCの実装者の設計により、できません。スピードアップ無効化を伴うGC。 GCがどのように/いつ実行されるのかについて心配しないでください。であることあなたを守り、見守っています...(弓が頭を下げ、拳が空へと昇ってきます)...
個人的には、自己ドキュメンテーションの形式として変数を使い終わったら、変数を明示的にnullに設定することがよくあります。宣言したり、使用したり、後でnullに設定したりしません。不要になった直後はnullにします。私は、「私は正式にあなたとやりました…消えて…」と明確に言っています。
GCの言語では無効化は必要ですか?いいえ。GCに役立ちますか?たぶん、いや、いや、確かにわからない、設計上、私は本当にそれを制御することができない、そしてこのバージョンでの今日の答えに関係なく、将来のGC実装は私の制御を超えて答えを変えるかもしれない。さらに、null化が最適化されている場合は、空想に過ぎません。コメントもしそうなら。
私の意図が私の足跡をたどる次の貧しい愚か者に対してより明確にするかどうか、そしてそれが「たぶん」場合によってはGCを支援することもありますが、それは私にとって価値があります。主にそれは私をきちんとしたそして明確に感じさせます、そしてMongoはきちんとして明確に感じるのが好きです。 :)
私はこのように見ます:プログラミング言語は他の人々に意図のアイデアとコンパイラに何をすべきかの仕事の要求を与えることを可能にするために存在します - コンパイラはCPUのために異なる要求に変換を要求しますどの言語、タブ設定、コメント、文体強調、変数名など、CPUがすべてのレジスタやオペコード、メモリ位置を調整するためのビットストリームについて教えてくれます。コードで書かれたものの多くは、指定した順序でCPUが消費したものに変換されません。私たちのC、C ++、C#、Lisp、Babel、アセンブラ、あるいは実際よりもむしろ理論であるものは何でも、作業宣言として書かれています。あなたが見るものはあなたが得るものではありません、はい、アセンブラ言語でさえも。
「不要なもの」(空白行など)の考え方は「ノイズにすぎずコードを雑然とさせること」にすぎません。それは私のキャリアの初期の頃でした。私は完全にそれを手に入れました。この時点で私はコードをより明確にするものに傾いています。私のプログラムに50行もの「ノイズ」を加えているわけではありません。
どの規則にも例外があります。揮発性メモリ、静的メモリ、競合状態、シングルトン、「古くなった」データの使用、およびそのような腐敗のシナリオでは、違います。自分のメモリを管理し、メモリの一部ではないため、アプロとしてロックおよび無効化する必要があります。 GCの宇宙 - 誰もがそれを理解しているといいのですが。 GCの言語の残りの部分は、必要性や保証されたパフォーマンスの向上ではなく、スタイルの問題です。
一日の終わりに、GCに適格なものとそうでないものを理解してください。適切にロック、破棄、および無効化する。ワックスオン、ワックスオフ。吸い込む、吐き出す。そして、他のすべてのもののために私は言う:それが気分が良ければ、それをしなさい。あなたの走行距離は変わるかもしれません...それがあるべきように...
いくつかのオブジェクトは.dispose()
リソースをメモリから強制的に削除するメソッド。