2012-05-10 12 views
0

私はC#を使用していますが、おそらくVB.NETでも同じです。私はオブジェクトのデストラクタにブレークポイントを設定して、いつ/削除されたかを知ることができます。 winformsでは基本クラスがSupressFinalizeを呼び出し、フォームデストラクタが呼び出されないようになっているので、私はそうすることはできないと思います。 オブジェクトがガベージコレクションされたかどうかを知る別の方法がありますか?キャッチ22のように思えるかもしれません。もしあなたが参照する必要があるのであれば、参照する必要がありますが、その参照を保持することによって収集されたガベージはそれを押しつぶさないからです。winformフォームがガベージコレクションされているかどうかを知る方法?

この「What strategies and tools are useful for finding memory leaks in .NET?」を読んだことがあります。この「大きな写真」を扱うためのツールやフレームワークがあることを理解しており、数週間後にこれらの方法のいくつかを試しています。今のところ、削除されていないフォームに関連したリークがあるかもしれないという本当に強い気持ちがあるので、この1つのことをチェックしたいだけです(そして私は知るために知りたい)。

私はDisposeを見ることができると知っていますが、Disposeを呼び出すことはできますが、依然としてフォームオブジェクトがまだ存在しています。その理論をテストするために、自分のフォームにコールバックイベント用に登録した既知の問題を作成し、フォームを登録解除せずにフォームを閉じました。確かに、Disposeが呼び出された(そして「処分する」は真実だった)が、イベントが解雇されたときに、それはすでに処分されていたフォームの中で私のブレークポイントに達した。

あなたの元の質問については

、あなたがその寿命に影響を与えずに、オブジェクトの存在を監視するために、弱い参照を使用することができます。

+2

イベントハンドラを実行するイベントを処理したフォームで実行できる場合は、間違いなくバグがあります。そして、おそらくフォームオブジェクトをリークするものです。 –

答えて

3

は本当にここに二つの問題があります。

あなたの基本的な質問は、ガベージコレクションとは何か、そしてそれがどのように機能するのか誤解していることを示唆しています。ガベージコレクションのポイントは、オブジェクトが収集されているかどうかを決して気にしないことです。代わりに、オブジェクトへの参照に焦点を当て、オブジェクトが再割り当てされているか、ルートのある参照からアクセスできない場合には、インスタンスを心配する必要はありません。インスタンスへの参照が心配です。

+0

WeakReference.IsAliveが私の必要とすることをします。ありがとうございます。私はGCを理解しており、そこにはオブジェクトへの各参照を示すツールがあることを知っています。それは私が長期的に焦点を当てる必要があるものです。今のところ、1つの特定のオブジェクトが収集されたかどうかを知る方法を探していただけです。 – eselk

0

管理対象言語の概念全体は、オブジェクトが実際にガベージコレクションされるときに気にする必要がないということです。たくさんの時間と労力がGCに入り、収集すべきオブジェクトを残さないようにしてはならないオブジェクトを収集しないようにします(世代を超えて渡すことを決めるときそれがあります)、これはすべて合理的に効率的に行われます。これは、オブジェクトが大量の管理対象リソースを消費し、IDisposable(DataTableやDataSetなど)を実装している場合でも、メモリがまだ消費されていて、それを破棄してもより速くガベージコレクションされるわけではありません(管理されたリソースがなくなるように、それを処分する必要があります)。

GCは、単独で放置すると最も効果的に機能し、手作業で収集を実行しようとすることで干渉するのではなく、機能するようになっています。これは、デバッグの目的やプログラム/言語の学習には便利なことがありますが、実際には本番アプリケーションには含まれません。

廃棄は、ガベージコレクションやオブジェクトの収集とは関係ありません。 Disposingは、unmangaedリソース(またはunmangaedリソースを保持している別のオブジェクト)を保持している管理オブジェクトを処理するための適切なメカニズムです。オブジェクトを破棄すると、その管理されていないリソースをクリアするように指示されますが、ガベージコレクタはそのオブジェクトの管理対象リソースを解放しません。デストラクタは、管理されていないリソースを解放する前に管理されたリソースを解放しないように、そこにありますが、管理対象リソースが解放される前に、非管理対象リソースが(disposeを介して)クリーンアップされることは完全に容認されます。

ここでは、プログラムがメモリリークを起こす可能性はありますが、いくつか質問がありますので、まず自分自身に質問する必要があります。漏れの大きさはどれくらいですか?それは1つのオフ、時間の経過とともに、私たちが関数Xなどを行うたびに連続的ですか?プログラムが破壊的(メモリ不足、他のプログラムのメモリ不足など)するほどのメモリを消費し、プログラムの一般的または正当な使用で発生する可能性があるのは、プログラムにとって何が必要でしょうか?通常、メモリの例外から抜け出すまで、またはそうでないプログラムのために物理メモリの不足が始まるまで、これらのタイプの質問を開始する必要はありません。これらの問題に気がつくと、不要になった非常に大きなオブジェクト(またはオブジェクトのコレクション)への参照を保持しているかどうかを調べるために、IDisposableを実装しているオブジェクトを探し出すことができます。

テキストの壁紙には申し訳ありません。

+0

これは、プロダクトコードではなく、デバッグ/ラーニングのみを対象としています。これはプロダクションプロジェクトの一部ですが、このコードは残されません。非常に特殊なタイプのメモリリークをチェックするための多くのツールの1つとして使用されています。避けたいのは、私たちが関数Xを実行するたびに、 "私は間違ってオブジェクトをピン止めしてしまうと成長する可能性があります。 – eselk

関連する問題