0

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

私はこれを読みました.NETでメモリリークを見つけるのに役立つ戦略とツールは何ですか? 、この「全体像」を処理するためのツールやフレームワークがあることを理解しています。数週間以内に、これらの方法のいくつかを試してみるつもりです。今のところ、フォームが削除されていないことに関連するリークが発生している可能性が非常に強いと感じているので、これを1つ確認したいだけです(そして、知るために知りたいだけです)。

Dispose を監視できることはわかっていますが、Dispose を呼び出すことはできると確信していますが、それでもフォーム オブジェクトは存在したままです。その理論をテストするために、フォームでコールバック イベントを登録した既知の問題を作成し、登録を解除せずにフォームを閉じました。案の定、Dispose が呼び出されました (そして「破棄」は true でした) が、後でイベントが発生したときに、既に破棄されていると思われるフォーム内のブレークポイントにヒットしました。

4

2 に答える 2

3

ここには実際には 2 つの問題があります。

元の質問については、 WeakReference を使用して、オブジェクトの存続期間に影響を与えることなくオブジェクトの存在を監視できます。

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

于 2012-05-10T05:10:11.037 に答える
0

マネージ言語の全体的な概念は、オブジェクトが実際にいつガベージ コレクションされるかを気にする必要がないということです。収集すべきでないオブジェクトを収集しないこと、収集すべきオブジェクトを残さないことを確認するために、GC には多くの時間と労力が費やされますそれは入っています)そして、これらすべてが合理的に効率的に行われます。これは、オブジェクトが大量のマネージ リソースを消費し、IDisposable (DataTable や DataSet など) も実装している場合に破棄された場合でも、メモリを大量に消費しており、破棄してもガベージ コレクションが速くなることはないことを意味します。 (ただし、管理されたリソースが確実になくなるように、それを破棄する必要があります)。

GC は、たとえば手動でコレクションを実行させようとして干渉するのではなく、そのままにしておくと最適に機能するように構築されています。これは、デバッグ目的やプログラム/言語についての学習に役立つ場合がありますが、実際には本番アプリケーションには属しません。

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

さて、これらすべてを考えると、プログラムでメモリ リークが発生する可能性は依然としてありますが、最初に自問する必要のある質問がいくつかあります。漏れの大きさは?関数 X などを実行するたびに、1 回限りの継続的なものですか? プログラムが大量のメモリを消費して破壊的 (メモリ不足、他のプログラムのメモリ不足など) になるには何が必要で、それはプログラムの一般的または正当な使用で発生する可能性がありますか? 通常、メモリ不足の例外が発生し始めるまで、またはそうすべきではないプログラムの物理メモリが不足し始めていることに気付くまで、これらのタイプの質問を開始する必要はありません。これらの問題に気付いた場合は、破棄されていない IDisposable を実装するオブジェクトを探し始めることができます。

テキストの壁で申し訳ありません。

于 2012-05-10T05:26:39.643 に答える