ホームページ >Java >&#&チュートリアル >Java 8 で、finalize() 呼び出しが予期せずストリームの終了を引き起こすのはなぜですか?
Java 8 での Finalize() 呼び出しについて
Java 7 から Java 8 への移行中に、メッセージ処理アプリケーションで例外が発生することがあります。ストリームの閉鎖に関連しています。調査の結果、ストリームを保持するオブジェクトに対して Finalize() が予期せず呼び出され、アクティブな読み取り操作中にオブジェクトが閉じられることが判明しました。
最初は不可解でしたが、この動作はガベージ コレクションのよく理解されていない側面に起因している可能性があります。スタック上にオブジェクトへの参照が存在し、アクティブなメソッド呼び出し中にも、オブジェクトは到達不能とみなされます。これは、後続のコードがその参照にアクセスしない場合に発生し、その参照が「デッド」になります。
簡略化された例でわかるように、アクティブなメソッドの実行中であっても、オブジェクトはファイナライズされ、ガベージ コレクションされる可能性があります。
class FinalizeThis { @Override protected void finalize() { System.out.println("finalized!"); } void loop() { for (int i = 0; i < 1,000,000,000; i++) { // Triggering GC with System.gc() doesn't guarantee garbage collection } } public static void main(String[] args) { new FinalizeThis().loop(); } }
この例では、FinalizeThis オブジェクトの参照はスコープ内に残りますが、それ以上の対話がないため、到達できません。その結果、ファイナライズとその後のガベージ コレクションの対象になります。
報告されたケースでは、MIMEBodyPart オブジェクトは m_ プレフィックスが付いたローカル変数に格納されている可能性があり、潜在的な到達不能の条件を満たしています。コメントで示唆されているように、オブジェクトの保存場所を変更すると、ファイナライズ動作が停止します。
このファイナライズの問題は、コンパイル ディレクティブを導入することで回避できることは注目に値します。 -Xcomp フラグは、実行前にメソッドのコンパイルを強制し、コンパイラが到達可能性分析を実行して、不当なファイナライゼーション呼び出しを回避できるようにします。
以上がJava 8 で、finalize() 呼び出しが予期せずストリームの終了を引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。