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