ホームページ > Java > &#&チュートリアル > 強力に到達可能な Java 8 オブジェクトが途中でファイナライズされるのはなぜですか?

強力に到達可能な Java 8 オブジェクトが途中でファイナライズされるのはなぜですか?

Mary-Kate Olsen
リリース: 2024-12-12 13:45:16
オリジナル
995 人が閲覧しました

Why Are My Strongly Reachable Java 8 Objects Being Finalized Prematurely?

「Java 8 の強く到達可能なオブジェクトで呼び出される Finalize()」

問題:

Java 7 で開発され、最近 Java 8 にアップグレードされたアプリケーションで時折例外が発生するストリームが途中で閉じられたことを示します。調査の結果、ファイナライザー スレッドが、ストリームを保持するオブジェクトに対して Finalize() を途中で呼び出していることが判明しました。これにより、クロージャがトリガーされます。

背景:

コード構造には MIME が含まれています。ライター (MIMEWriter)、MIME ボディ部分(MIMEBodyPart)、および添付ファイルを表す入力ストリーム (InflaterInputStream)。 MIMEBodyPart は HTTPMessage を拡張します。これには、基になるストリームを閉じる close() メソッドが含まれます。さらに、HTTPMessage には、ストリームがまだ開いている場合に close() の呼び出しを試みる Finalize() メソッドがあります。

イベントのシーケンス:

  1. MIMEWriter は添付ファイル部分のヘッダーを書き込みます。
  2. MIMEBodyPart は、入力ストリームからチャンクをコピーする IOUtil.copy を使用して本文のコンテンツを書き込みます。出力ストリーム。
  3. IOUtil.copy がチャンクを読み取ろうとしましたが、閉じられたストリームに遭遇し、例外がトリガーされました。

原因:

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート