FinalReferenceの見積もり
このクラスはパッケージタイプであり、公開部分ではなく、参照から継承することを示しています。つまり、特定の参照タイプでもあります。したがって、各オブジェクトが包まれてリサイクルされる前に、指定されたreferqyebcequeueに配置されます。
この参照オブジェクトは、ファイナライズメソッドを備えたクラスに特別に使用されます。対応するメソッドを持つすべてのオブジェクトは、FinalReferneceオブジェクトとしてカプセル化されることを理解できます。
ファイナライズメソッドはオブジェクトによって定義されるため、デフォルトの実装は空です。その後、この方法が書き換えられた場合、メソッド本体は間違いなく空になりません。この違いは、これを通して行うことができます。ファイナライズメソッドが空でないクラスを実装する限り、生成されたオブジェクトはFinalReferneceに登録する必要があります。
この手順は、NewInstance中にObject Default Constructorメソッドを呼び出すことにより、それに応じて登録できます。
Finalizer#登録方法
この方法が主に呼ばれると、対応するファイナイザーオブジェクトが生成され、ファイナイザーオブジェクトはFinalReferenceから継承されます。この方法は次のように宣言されています。
/ * VMによって呼び出された */static voidレジスタ(Object finalizee){new finalizer(finalizee);}上記のコメントからわかるように、この方法は特定の期間にJVMによって呼び出されます。
次に、以下に示すように、Finalizerのコンストラクターに切り替えます。
Private Finalizer(Object Finalizee){Super(Finantizee、Queue);追加();}対応する参照オブジェクトは、キューから呼び戻されることがわかります。 ADDの機能は、メソッドをまだ完成させていないすべてのオブジェクトを保存し、End System.shutdownでそれを呼び出すことです。 Runtime#runFinalizersOnExitで設定します。
参照キュー
この参照キューは、対応する参照オブジェクトの内部オブジェクトがリサイクルされる前にこのキューに配置されます(詳細な説明は、参照に関する別の記事で説明されます。)対応するオブジェクトのみをこのキューから取得する必要があるため、このオブジェクトは間違いなくリサイクルされる準備ができています。
次に、リサイクル前に対応するファイナライズメソッドを呼び出します。
FinalizerThreadスレッド
このスレッドは、キューからデータを取得し続け、対応するファイナライズメソッドを呼び出します。対応するコードは次のとおりです。
for(;;){try {finalizer f =(finalizer)queue.remove(); F.Runfinalizer(JLA); } catch(arternedexception x){//無視して続行}}対応するRunfinalizerは次のとおりです。
同期(this){if(hasbeenfinalized())return; remove();} try {object finalize = this.get(); if(finantizee!= null &&!(fanizee instance of java.lang.enum)){jla.invokefinalize(finalizee); / *この変数を含むスタックスロットをクリアして、保守的なGC/ Finantizee = nullで誤った保持の可能性を減らします。 }} catch(throwable x){} super.clear();上記のロジックでは、最初に呼び出して削除し、ファイナライズから削除します。この方法は、各オブジェクトの最終化がせいぜい1回だけ呼び出されること、つまり現在の呼び出しが完了することを確認するためです。それは対応する状態、つまり、hasbeenfinalizedのリターンを真のリターンに記録します(実際、それは次のポインターをそれ自体に向けることを意味します。つまり、それは決して最終化されておらず、再びファイナライズを呼び出す必要はありません)。
次に、対応するファイナライズメソッドを呼び出すことです。上記のjla.invokeFinalize 、実際に対応するオブジェクトのファイナライズ方法を呼び出すことです。このプロセスでは、元のオブジェクトはGETによって最初に取得されます。 JVMプロセス全体では、最終化のためにリサイクルする前に参照がnullに設定されていません。ここで、対応する参照オブジェクトはいつでも取得できるからです。
処理後、対応するクリアが最終的に呼び出され、対応する参照をクリアします。これにより、参照する他のオブジェクトがない最終的な参照の効果が得られます。
上記の処理では、Call Callizeの時間に制限はありません。したがって、オブジェクトの最終化がゆっくりと呼ばれると、リサイクルチェーン全体の実行に影響し、対応するOOM例外が生成されます。したがって、特別な場合がない限り、ファイナライズを書き直さないでください。対応するシナリオを処理する他の方法があるはずです。たとえば、グアバでの最終化。
ファイナルライザーはスレッドを開始します
上記のスレッドでは、対応するプロセスの起動時に開始されます。オブジェクトはregister(object)を呼び出すことにより、ファイナルライザークラスの初期化をトリガーすることが理解できます。次に、静的初期化ブロックで、対応するリサイクルスレッドが開始されます。対応する初期化コードは次のとおりです。
static {threadgroup tg = thread.currentthread()。getThreadGroup(); for(threadgroup tgn = tg; tgn!= null; tg = tgn、tgn = tg.getparent()); Thread Finalizer = new FinalizerThread(TG); finalizer.setpriority(thread.max_priority -2); finalizer.setdaemon(true); finalizer.start();}上記の静的は、静的初期化ブロックです。つまり、クラスファイナライザーが使用されている限り、対応する呼び出しがトリガーされます。ここで使用されるスレッドグループはシステムスレッドグループであり、優先度はまだ比較的高く、バックグラウンドスレッドとして構成されています。
jstackを使用してスレッドを印刷する場合、図の下に示されているスレッドがここから開始されます。下の図に示すように
要約します
ファイナルライザー全体は、JVMと対応するJavaクラスによる最終参照を通じて連携します。すべてがJVMによって実装されているわけではないため、根本的すぎるのではなく、対応するセマンティクスを実装することは考えることができます。すべてが通常のJavaによって行われ、JVMによって協力されます。プロセス全体を理解することは、Java自体の実行メカニズムの理解でもあります。