9

この質問にはすでに答えがあります。

私は自分の会社の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ブロックに入れる理由はありますか?これが広告内のメモリリークを引き起こす可能性がある場合はありますか?

ありがとうございます。


  • .NETのメモリ管理がVBのCOM管理とどのように異なるのかを学びたくなかったEx VB(classic)プログラマのように思えます。 - Damien_The_Unbeliever
  • 私はそれが一種の良い処分方法だと思います - Matias Cicero
  • @ MatiCicero:いいえ、そうではありません。理解の欠如を裏切るのは、貨物カルトプログラミングの典型的なケースです。 - Michael Borgwardt

3 답변


14

これは範囲によって異なります。

あなたの例では、oプロパティの範囲内でのみ定義されます。だから無駄になります。しかし、言うoクラスの範囲内でした。それからそれはの状態を示すために意味をなさないo

現状のままでは、必要ありません。


  • しかし、作成されたオブジェクトは、それにもかかわらずメモリを消費します。これは、nullに設定されているオブジェクトへの単なる参照です。 GCはオブジェクトが最後に使用された日時を認識していないため、すべての参照をnullに設定して明示的に通知する必要はありませんか。 - CodyEngel
  • 参照がまだスコープ内にある場合は、nullに設定する必要があります。GCがそれを使用していないことをGCが認識する方法です。 - Russell at ISC
  • @ラッセル、ああ、GCの動作は違うと思いました。 - CodyEngel

6

GCにオブジェクトをできるだけ早く収集させることが目的であれば、それはまったく役に立ちません。

オブジェクトがo後のどこでも使用されていませんtryブロック、それが最後に使用された直後(すなわち、変数の前)に収集のために選択されます。o範囲外になり、それがfinallyブロック)。

関連するメモについては、Lippert'sを参照してください。建設破壊


  • Eric Lippertの記事へのリンクは+1です。 「スコープ」の概念は、以下の点に注意してください。 C#では、中括弧のネストとは関係がありません。 - OldFart

-1

これを行う理由は少なくとも2つあります。まず、このパターンを使用することは、変数の再利用によって引き起こされるバグを捉えるのに一貫して役立ちます(つまり、これがより大きなコードシーケンスの一部である場合、変数名 'o'は実行の後半で異なるオブジェクトを保持します)。明示的にnullを代入することで、後で同じオブジェクトを使用しようとしたときにそのようなコードでエラーが発生するようになります(大きいブロックの場合は誤ってコンストラクタをコメントアウトしたとします)。

次に、nullを割り当てると、オブジェクトがGCによる収集に使用できる可能性があることが保証されます。クラス変数にとってはより重要ですが、ローカル変数でも利益を得ることができます。オブジェクトは存在しないので読む代入によって、既存の最適化が代入を含むことによって影響されるべきではありません(ただし、不必要です)。同様に、代入自体も完全に最適化される可能性があります(その後オブジェクトにアクセスしない場合)が、これらの最適化は両方ともコンパイラーの目的であるため、この構造を使用すると、含まれない代替コンパイルモデルの初期コレクションが可能になります。そのような最適化

それは私が持っているよりもC#言語の仕様にもっと精通している必要があるでしょうが、私はそれらがオブジェクトであるとは述べていないと思いますしなければならない最後のアクセスの直後にコレクションに割り当てられます。この種の仮定を単一のコンパイラ、またはコンパイラのグループの現在のアクションのいずれかに基づいて行うと、後で同じ原則に従わない環境に移植しようとしたときにさらに作業が進む可能性があります。

メモリリークの可能性については、GCが正しく動作していて、オブジェクトが特別な処理を必要としていなければ問題はありません。実際、未使用のメモリへの潜在的な参照を削除して再生できるようにします。特別な処分が必要な物については、私はそれらが同じ場所で取り扱われることを期待するでしょう。


  • ここで何を言おうとしているのかはわかりませんが、これは単なるテキストの壁にすぎません。あなたはあなたの答えの一部を段落に分けることを検討したいかもしれません。 - Damien_The_Unbeliever

リンクされた質問


関連する質問

最近の質問