2011-04-13 11 views
1

ガベージコレクションの仕組みやメモリリークの原因については、あまり知られていません。しかし、私はそれを心配しており、より効率的なコードを書こうと思っています。だから、Asp.Net Webアプリケーションである私が取り組んでいるプロジェクトでは、Sessionがglobal.asaxで始まり、Session変数に格納されるときにカスタムDataCriteriaのインスタンスが作成されます。このカスタムDataCriteriaは、CRUDメソッドのためにデータベースと通信するために使用しているものです。Session変数に格納されているオブジェクトを参照する変数は、GCによって収集されますか?

最初の質問は、Personクラスがあり、このPersonクラスにDataCriteriaのSession変数インスタンスに設定されているDataCriteriaフィールドがあることです。 Personのインスタンスは、Sessionが終了するまで処分されないDataCriteriaのインスタンスへの参照を保持しているので、そのPersonのインスタンスを収集できるかどうか。または、そのセッションが終了するまで、人のすべてのインスタンスは処分されません。

2番目の質問はより一般的ですが、同じ問題です。基本的に私は、DataCriteriaのSession変数インスタンスを参照するメソッドで宣言されている変数がGCによって収集できるのだろうかと疑問に思っていますか?また、セッションが終了するまで、それも残っていますか?

私はここで私に与えることができるすべてのアドバイスに感謝します。ガベージコレクションを理解し、メモリリークを回避するための良い読み方が分かっていれば、私もそのことについて聞きたいです。

答えて

2

オブジェクトが保持する参照は、ガベージコレクションの可用性に影響しません。しかし、その逆は真ではない。たとえば、インスタンスAがインスタンスBを保持するフィールドを持っているとします.Bが静的であるか、それ以外の場合は「長期間」であっても、Aは他のものがそれを参照するとすぐにガベージコレクションに使用可能になります。ただし、Aがガベージコレクションに使用できるようになるまで、Bはガベージコレクション以上は少なくともにはなりません。

物事が少し奇妙になることがあるところでは、参照があまりにも明白でないところです。たとえば、インスタンスCは、CがDによって公開されたイベントにサブスクライブするときインスタンスDによって参照されます。つまり、Dが長期間存続する場合、イベントからのサブスクライブを解除しない限り、CはDより前のガベージコレクションに使用できなくなります。イベントや他の代理人を介して参照される参照は、実際には.NETアプリケーションの「メモリ」リークの大半を占めています。 (実際には、実際のオブジェクトインスタンスで使用されていないメモリをクリーンアップすることは実際にはないので、実際にはメモリリークではありません)。

+0

ありがとう、それは素晴らしい答えです。私は実際にイベントハンドラについて尋ねるつもりでした。だから、インスタンスCがそれ自身のイベントを購読するのはどうですか?これらをDisposeメソッドで購読解除する必要があります。それとも必要ないのですか? Disposeメソッドで処理する必要がある他の参照イベントへのサブスクリプションだけですか? – jhorton

+0

自己参照はオブジェクトを存続させません。 (同様に、他のものによって参照されていないインスタンスのセット間の参照は、それらのいずれかを生き残らせません)。これは、自分自身のイベントからの購読を解除する必要がないことを意味します。オブジェクトのDisposeメソッド内では、それ自身のイベントをクリアし、他のオブジェクトのイベントからの登録を解除する必要があるだけです。 –

+0

したがって、PersonクラスがINotifyPropertyChangedインタフェースを実装する別のクラスを継承する場合。 Personインスタンスには、PropertyChangedイベントのハンドラがあります。それはDisposeで私が退会しなければならないハンドラですか?私はそれをはっきりと理解するために実際の例が必要だと思います。 – jhorton

1

オブジェクト参照は、有向グラフ - オブジェクトA参照オブジェクトBを構成します.Aが収集されるまでは、Bはできません。

セッションは、物事を参照する別のオブジェクトです。この場合、オブジェクトAはオブジェクトBを参照しています。

あなたのケースでは、PersonがSessionにも格納されているものを参照しているからといって、SessionがなくなるまでPersonが周りにいるわけではありません。 Sessionがあなたの人を参照していない限り、その生涯はリンクされていません。

ここで気を付けなければならないのは、あなたのDataCriteriaが参照するものです。データベース接続やその他のオブジェクトを保持している場合は、セッションが存続する限り存続します。

+0

ありがとうございました。あなたたちはこれでとても助けになりました。私はあなたも答えとしてマークしますが、彼女はそのイベントハンドラ部分を含んでいました。しかし、これを明確にしてくれてありがとうございます。 – jhorton

関連する問題