この質問にはすでに答えがあります。
私は自分の会社のC#コードを整理していますが、このアプリケーションを作成した業者がオブジェクト参照をnullに設定し続けていることに気付いています。
例:
get {
Object o = new Object(); // create a new object that is accessed by the reference 'o'
try {
// Do something with the object
}
finally {
o = null; // set the reference to null
}
}
私が理解していることから、作成されたオブジェクトはまだ存在しています。他に参照がある場合は、アクセスできない可能性がありますが、GCが起動してクリーンアップするまで存在し続けます。
これをfinallyブロックに入れる理由はありますか?これが広告内のメモリリークを引き起こす可能性がある場合はありますか?
ありがとうございます。
これは範囲によって異なります。
あなたの例では、o
プロパティの範囲内でのみ定義されます。だから無駄になります。しかし、言うo
クラスの範囲内でした。それからそれはの状態を示すために意味をなさないo
。
現状のままでは、必要ありません。
これを行う理由は少なくとも2つあります。まず、このパターンを使用することは、変数の再利用によって引き起こされるバグを捉えるのに一貫して役立ちます(つまり、これがより大きなコードシーケンスの一部である場合、変数名 'o'は実行の後半で異なるオブジェクトを保持します)。明示的にnullを代入することで、後で同じオブジェクトを使用しようとしたときにそのようなコードでエラーが発生するようになります(大きいブロックの場合は誤ってコンストラクタをコメントアウトしたとします)。
次に、nullを割り当てると、オブジェクトがGCによる収集に使用できる可能性があることが保証されます。クラス変数にとってはより重要ですが、ローカル変数でも利益を得ることができます。オブジェクトは存在しないので読む代入によって、既存の最適化が代入を含むことによって影響されるべきではありません(ただし、不必要です)。同様に、代入自体も完全に最適化される可能性があります(その後オブジェクトにアクセスしない場合)が、これらの最適化は両方ともコンパイラーの目的であるため、この構造を使用すると、含まれない代替コンパイルモデルの初期コレクションが可能になります。そのような最適化
それは私が持っているよりもC#言語の仕様にもっと精通している必要があるでしょうが、私はそれらがオブジェクトであるとは述べていないと思いますしなければならない最後のアクセスの直後にコレクションに割り当てられます。この種の仮定を単一のコンパイラ、またはコンパイラのグループの現在のアクションのいずれかに基づいて行うと、後で同じ原則に従わない環境に移植しようとしたときにさらに作業が進む可能性があります。
メモリリークの可能性については、GCが正しく動作していて、オブジェクトが特別な処理を必要としていなければ問題はありません。実際、未使用のメモリへの潜在的な参照を削除して再生できるようにします。特別な処分が必要な物については、私はそれらが同じ場所で取り扱われることを期待するでしょう。