1

私は DataGridView にデータ バインド オブジェクトを介して定期的に値を設定していますが、「ログ サイクル」中に行数が数千になる可能性があります。

新しい「ログ サイクル」が始まると、基になるデータ ソースがクリアされ、プロセスが再び開始されるため、グリッドがクリアされます。

これで問題ありませんが、前回の実行には時間がかかるため、以前の行はすべて第 2 世代のオブジェクトになり、完全な GC でガベージ コレクションのみが行われました。

ただし、最初の GC はそれらすべてをファイナライザー キューに送信するため、それらをクリアするには 2 回のフル GC が必要です。これは、2 倍の長さのメモリを占有することを意味します。

リフレクターを使用すると、DataGridViewRow にはファイナライザー メソッドがないことがわかりますが、DataGridViewBand オブジェクトから継承されます。これは、パブリック Dispose() メソッドを介して GC.SuppressFinalize(this) を呼び出します。

私の質問は、なぜ私の DataGridViewRows が最初のフル GC で収集されず、別の GC を待っているファイナライザー キューに入れられないのですか?

(ここでの私の仮定は、ファイナライザーのないオブジェクトはファイナライザー キューに配置されるべきではなく、ファイナライザーを持っているが GC.SuppressFinalize を呼び出すオブジェクトもキューに配置されないということです。この仮定は正しいですか?)

ありがとう。

4

2 に答える 2

3

への呼び出しは、基本的に、ファイナライズ中に発生するクリーンアップ動作が ( への呼び出しを介して) 既に発生しており、ファイナライズを再度実行する必要がないことをGC.SuppressFinalize(this)GC に伝えます。Dispose()これは、オブジェクトがファイナライズ キューに配置されるかどうかには関係ありません。

ファイナライズ可能なオブジェクトがインスタンス化 ( newed) されるたびに、ファイナライズ キューに配置されます。ファイナライズ キューは、完全な GC コレクション (Gen2 コレクション) ごとにのみ処理されます。ファイナライズ可能なオブジェクトの問題の 1 つは、オブジェクトが実際に収集される前に、少なくとも1 つの余分な GC サイクルに耐えられることです。

于 2009-10-07T19:26:25.183 に答える
0

オブジェクトを破棄しないと、ファイナライズが抑制されません。

于 2009-10-07T19:19:23.653 に答える