あなたはそれを完全に間違っています。
簡単な答え:
finalize()
オブジェクトがガベージ コレクションの準備が整う直前に (開いているファイルなどの) リソースをクリーンアップする手段です (オブジェクトへの強い参照がない場合)。呼び出される場合と呼び出されない場合があります。これは、メモリ解放の一歩先を行っています。
長い答え:
finalize() メソッドの呼び出しを担当するファイナライザー スレッドと呼ばれる別のデーモン スレッドがあります。ファイナライズ キューは、finalize() メソッドを呼び出す準備が整ったオブジェクトが配置されるキューです。
- オブジェクトが作成されると、JVM はユーザーが finalize() メソッドをオーバーライドしたかどうかをチェックします。ある場合、この特定のオブジェクトには finalize() メソッドがあることが内部的に記録されます。
オブジェクトがガベージ コレクションの準備ができると、ガベージ コレクタ スレッドは、この特定のオブジェクトに (1) で説明したテーブルからの finalize() があるかどうかをチェックします。
ファイナライザー スレッドはキューをポーリングし続けます。キュー内のすべてのオブジェクトに対して、その finalize() メソッドが呼び出されます。(2) からの finalize() サイクルを呼び出した後、再び繰り返されます。このオブジェクトがまだ強い参照を持っていない場合は、GC に送信されます。存在する場合は、(2b) でエントリが削除されたため、ALWAYS (2a) が呼び出されます。
Basically finalize() method is only called once.
では、上記のサイクルの問題は何でしょうか?
(1)より。オブジェクトの作成に余分な時間がかかります。Javaでのメモリ割り当ては、malloc/callocなどよりも5倍から10倍高速です。得られた時間は、テーブル内のオブジェクトに注意するなどの手順ですべて失われます。私は一度試しました。ループ内に 100000 個のオブジェクトを作成し、2 つのケースでプログラムが終了するまでの時間を測定します。20% 高速であることがわかりました。
(2b) から: メモリ リークと飢餓。キュー内のオブジェクトが多くのメモリ リソースへの参照を持っている場合、このオブジェクトが GC の準備ができていない限り、それらのオブジェクトはすべて解放されません。すべてのオブジェクトが重いオブジェクトである場合は、不足する可能性があります。
(2b) より: finalize() は 1 回だけ呼び出されるため、finalize() で「この」オブジェクトへの強い参照があった場合はどうなるでしょうか。次にオブジェクトの finalie() が呼び出されないため、オブジェクトが一貫性のない状態のままになる可能性があります。
finalize() 内で例外がスローされた場合、それは無視されます。
GC がいつ呼び出されるかを制御できないため、 finalize() がいつ呼び出されるかはわかりません。finalize() の値を出力しているのに、finalize() が呼び出されるまでにプログラムが終了している可能性があるため、出力が表示されないことがあります。
したがって、使用は避けてください。代わりに、必要なリソースや最終ログなどを閉じるメソッド dispose() を作成します。