[ファイナライズプロセスの内部についてさらに追加したかっただけ]
したがって、オブジェクトを作成し、オブジェクトが収集されFinalize
たら、オブジェクトのメソッドを呼び出す必要があります。しかし、ファイナライズには、この非常に単純な仮定以外にもあります。
短い概念::
オブジェクトがFinalize
メソッドを実装していない場合、メモリはすぐに再利用され
ます。もちろん、アプリケーションコードからアクセスすることはできません
実装するオブジェクトFinalize
メソッドのコンセプト/実装はApplication Roots
、Finalization Queue
、Freacheable Queue
彼らは再利用することができます前に来ます。
アプリケーションコードで到達できないオブジェクトはゴミと見なされます
前提::クラス/オブジェクトA、B、D、G、HはFinalize
メソッドを実装せず、C、E、F、I、JはFinalize
メソッドを実装します。
アプリケーションが新しいオブジェクトを作成すると、新しい演算子はヒープからメモリを割り当てます。オブジェクトのタイプにFinalize
メソッドが含まれている場合、オブジェクトへのポインタがファイナライズキューに置かれます。
したがって、オブジェクトC、E、F、I、Jへのポインタがファイナライズキューに追加されます。ファイナライズキューは、ガベージコレクタによって制御される内部データ構造です。キュー内の各エントリは、オブジェクトのメモリを解放する前にメソッドを呼び出す必要があるオブジェクトを指します。以下の図は、いくつかのオブジェクトを含むヒープを示しています。これらのオブジェクトのいくつかは、アプリケーションのルートから到達可能です
Finalize
、そうでないものもあります。オブジェクトC、E、F、I、およびJが作成されると、.Netフレームワークは、これらのオブジェクトにFinalize
メソッドがあり、これらのオブジェクトへのポインターがファイナライズキューに追加されることを検出します。
GCが発生すると(最初のコレクション)、オブジェクトB、E、G、H、I、およびJはガベージであると判断されます。A、C、D、Fは、上の黄色のボックスからの矢印で描かれたアプリケーションコードから到達可能であるためです。
ガベージコレクターは、ファイナライズキューをスキャンして、これらのオブジェクトへのポインターを探します。ポインターが見つかると、そのポインターはファイナライズキューから削除され、フリーチ可能なキュー(「F到達可能」)に追加されます。freachableキューは、ガベージコレクタによって制御される別の内部データ構造です。フリーチ可能なキューの各ポインターは、メソッドを呼び出す準備ができているオブジェクトを識別します。
Finalize
コレクション(最初のコレクション)の後、マネージヒープは次の図のようになります。以下の説明::
1.)オブジェクトB、G、およびHが占有するメモリは、呼び出す必要のあるfinalizeメソッドがなかったため、すぐに再利用されました。
2.) ただし、オブジェクトE、I、およびJが占有するメモリは、Finalize
メソッドがまだ呼び出されていないため、再利用できませんでした。
Finalizeメソッドの呼び出しは、到達可能なキューによって行われます。
3.) A、C、D、Fは、上の黄色のボックスから矢印で描かれたアプリケーションコードで到達可能であるため、いかなる場合でも収集されません。
Finalizeメソッドの呼び出し専用の特別なランタイムスレッドがあります。フリーチ可能なキューが空の場合(通常はそうです)、このスレッドはスリープします。ただし、エントリが表示されると、このスレッドはウェイクし、キューから各エントリを削除して、各オブジェクトのFinalizeメソッドを呼び出します。ガベージコレクターは再利用可能なメモリを圧縮し、特別なランタイムスレッドは、各オブジェクトのメソッドを実行して、フリーチ可能なキューを空にしますFinalize
。だから、最後にあなたのFinalizeメソッドが実行されるときです
次にガベージコレクターが呼び出されたとき(2番目のコレクション)、アプリケーションのルートがそれを指していなくて、フリーチ可能なキューがそれを指していません(EMPTYも)ので、完成したオブジェクトは本当にガベージであることがわかります。したがって、オブジェクト(E、I、J)のメモリは単にヒープから解放されます。下の図を参照して、上の図と比較してください
ここで理解しておくべき重要なことは、ファイナライズが必要なオブジェクトが使用するメモリを再利用するには、2つのGCが必要であることです。実際には、これらのオブジェクトは古い世代に昇格される可能性があるため、3つ以上のコレクションが必要になる場合もあります。
注:: freachableキューはグローバルと静的変数が根で同じようにルートであると考えられています。したがって、オブジェクトがフリーチ可能なキューにある場合、そのオブジェクトは到達可能であり、ガベージではありません。
最後の注意として、アプリケーションのデバッグは1つのことであり、ガベージコレクションは別のものであり、動作が異なることを覚えておいてください。これまでのところ、アプリケーションをデバッグするだけではガベージコレクションを感じることができません。さらに、メモリを調査したい場合は、ここから始めてください。