2

finalizeオブジェクトがガベージ コレクションの対象であると JVM が判断した後、Java のメソッドが呼び出されます。これがいつ発生するか、またはプログラムが終了する前に発生するかどうかについて、実際の保証はありません。私の質問は、実際にガベージ コレクションされたオブジェクトに対して呼び出されることfinalizeが保証されているかどうかです。世代別 GC の最も若い世代のオブジェクトについて具体的に考えています。

世代別 GC では、ライブ オブジェクトのみが走査され、新しい空間にコピーされる単純なマーク スイープ コレクションを使用して、最も若い世代が GC されることがよくあります。したがって、最も若い世代のガベージは実際にはトラバースされません。finalizeまた、ガベージがトラバースされない場合、ガベージになるオブジェクトに対して が呼び出されることをどのように保証するのでしょうか? a) 最年少世代でガベージになるこれらのオブジェクトに対して呼び出される保証がないfinalize、または b)finalize呼び出される保証はあるが、オーバーライドするオブジェクトfinalizeは何らかの方法で処理が異なるようです。

4

2 に答える 2

1

私の質問は、実際にガベージ コレクションされたオブジェクトに対して finalize が呼び出されることが保証されているかどうかです。

実際にはそうです。

実際の保証は、オブジェクトが最終的に回収される前に finalize メソッドが呼び出されることです。

また、ガベージがトラバースされない場合、ガベージになるオブジェクトに対して finalize が呼び出されることをどのように保証するのでしょうか?

トラバーサル (マーキング) 中は finalize メソッドは呼び出されません。これは、マーク フェーズでマークされなかったオブジェクトに対して後で呼び出されます。マーク フェーズでマークされたオブジェクトは到達可能であり、再利用の候補ではありません。


問題は、どのオブジェクトがマークされていないかを JVM がどのように認識するかということです。これには、ガベージであっても、ナーサリ内のすべてのオブジェクトの走査が必要になるようです。

それも一つの方法でしょう。

別の方法は、オブジェクトの「ファイナライズ可能な」リストの特別な (非 GC ルート) リストを持つことです。ライブ オブジェクトが退避された後、リストが走査されて、ファイナライズ可能なすべてのオブジェクトの古い領域のコピーが調べられます。退避されていないものは、ファイナライズする必要があります。

そして、他のスキームもあるかもしれません。

それがどのように行われるかを本当に知りたい場合は、ガベージ コレクターのソースを無料で入手できます。

于 2013-10-09T15:00:06.433 に答える
1

これは、ファイナライズ可能なオブジェクトの 1 つの実装がどのように機能するかを示す記事ですhttp://www.fasterj.com/articles/finalizer1.shtml

于 2013-10-09T19:00:21.260 に答える