「Java 8 の強く到達可能なオブジェクトで呼び出される Finalize()」
問題:
Java 7 で開発され、最近 Java 8 にアップグレードされたアプリケーションで時折例外が発生するストリームが途中で閉じられたことを示します。調査の結果、ファイナライザー スレッドが、ストリームを保持するオブジェクトに対して Finalize() を途中で呼び出していることが判明しました。これにより、クロージャがトリガーされます。
背景:
コード構造には MIME が含まれています。ライター (MIMEWriter)、MIME ボディ部分(MIMEBodyPart)、および添付ファイルを表す入力ストリーム (InflaterInputStream)。 MIMEBodyPart は HTTPMessage を拡張します。これには、基になるストリームを閉じる close() メソッドが含まれます。さらに、HTTPMessage には、ストリームがまだ開いている場合に close() の呼び出しを試みる Finalize() メソッドがあります。
イベントのシーケンス:
原因:
MIMEBodyPart.finalize() メソッドは、IOUtil.copy がアクティブに実行されている間に、ファイナライザー スレッドによって途中で呼び出されます。 Java 8 では、オブジェクトがローカル変数またはアクティブなメソッド呼び出しによって参照されている場合でも、オブジェクトをファイナライズできるようにするガベージ コレクションの最適化が導入されました。
MIMEBodyPart オブジェクトは、確かに MIMEBodyPart.writeBodyPartContent のスタック フレームから到達可能です。これは、 JVM はそれをファイナライズしようとしてはいけません。ただし、IOUtil.copy ループ内の MIMEBodyPart への参照は積極的に使用されていないため、到達不能になり、ガベージ コレクションとファイナライズの対象になります。
結果:
完了が早すぎると、誤った動作や潜在的なデータが発生する可能性がありますloss.
解決策:
推奨されるアプローチは、独自のライブラリを再検討し、finalize() メソッドの使用を排除することです。 Java Mail の MIME ライブラリでは問題が発生しなかったため、これが代替手段として機能する可能性があります。
代替推測:
もう 1 つの考えられる説明には、InflaterInputStream が関係しています。 InflaterInputStream 内の中断不可能な操作中に MIMEBodyPart.finalize() メソッドが呼び出される場合、ストリームが中断され、例外がトリガーされる可能性があります。ただし、この仮説にはさらなる調査が必要です。
以上が強力に到達可能な Java 8 オブジェクトが途中でファイナライズされるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。