まず、すべてのオブジェクトに対してファイナライズが実行されるという保証はありません。オブジェクトに関連付けられたネイティブコードに割り当てられたメモリーを解放するために使用できますが、純粋なJavaコードの場合、ほとんどの場合はリソースをクリーンアップする「バックアップ」メカニズムを実行するだけです。これは、ほとんどの場合、手動でリソースを解放しなければならないことを意味します。ファイナライザは、標準的な方法で行うことを忘れてしまった場合には、一種のヘルパーだけで動作します。ただし、これらをクリーンアップの唯一または主要なメカニズムとして使用することはできません。さらに一般的には、ファイナライザが実行されているかどうかに依存するコードを書くべきではありません。
広告1。私が知る限り、どのスレッドがfinalize()
を呼び出すかは保証されていませんが、実際にはこれはおそらくGCスレッドの1つになります。
広告2.新しいオブジェクトをインスタンス化することは許可されています。しかし、ファイナライザでオブジェクト参照を処理することにはいくつかの落とし穴があります。特に、一部のライブオブジェクトでファイナライズされているオブジェクトへのハードリファレンスを格納すると、ガーベジコレクションされそうなオブジェクトがクリーンアップされるのを防ぐことができます。このようなオブジェクトの復活は、制御不能になった場合にリソースを枯渇させる可能性があります。 finalize()
の例外についても注意してください。終了すると停止することがありますが、プログラムで自動的に学習する方法はありません。 try-catchブロックにコードをラップして、自分で情報を伝播する必要があります。また、ファイナライザの実行時間が長くなると、オブジェクトのキューが構築され、大量のメモリが消費される可能性があります。他のいくつかの注目すべき問題と制限は、this JavaWorld articleに記載されています。
広告3.ファイナライザから静的メソッドを呼び出すときに問題はありません。
Ad 4.ポイント2で述べたように、ファイナライズ時に別のライブオブジェクトに参照を置くことで、オブジェクトがガベージコレクション(復活)するのを防ぐことができます。しかし、これは微妙な動作であり、おそらく良い習慣ではありません。
要約すると、ファイナライザを使用してリソースをクリーンアップすることはできません。あなたは手動で処理する必要があり、ケースのファイナライザは、せいぜいコードをいくつかの程度まで覆い隠すためのバックアップメカニズムとして使用することをお勧めします。残念ながら、ファイナライザを使用してOpenGLリソースをクリーンアップすることで、APIをより良くする考えはおそらくうまくいかないでしょう。
これはあなたの質問に対する直接的な答えではありませんが、ファイナライズが頻繁に使用されない多くの理由の1つであるファイナンスが呼び出されることは保証されていません。 (編集:それがあってもJava管理メモリのメモリ圧迫のために呼び出されます。つまり、他のリソースを解放するためにそれを使用しようとすると、それらを使い果たしてあなたのプログラムがクラッシュしても、GCがGCを実行して(例えば)ファイルハンドルを再利用することをJavaが知らないからです。 – jacobm