Java 7 から Java 8 へのアップグレードでは、読み取り操作中にストリームの閉鎖を示す例外が発生する場合があります。これは、ストリームを保持するオブジェクトに対してファイナライズ スレッドが Finalize() を呼び出し、その後ストリームを閉じることが原因で発生します。
提供されたコードを考慮すると、MIMEBodyPart によって拡張された HTTPMessage の Finalize() メソッドが close() を呼び出します。関連付けられたストリームを閉じます。 MIMEWriter.writePart() の実行中、IOUtils.copy は入力ストリームからチャンクを枯渇するまで読み取ります。
この問題は、IOUtils.copy の実行中に HTTPMessage.finalize() が実行されると発生し、ストリームが閉じられます。例外。 MIMEBodyPart オブジェクトがスタック フレームから到達可能である間、JVM は Finalize() を呼び出します。この動作は複雑です。
潜在的な説明
ローカル スタック変数内のオブジェクトへの参照やアクティブなメソッド呼び出しがあっても、オブジェクトが「到達不能」と見なされた場合、ファイナライズされ、ガベージ コレクションされる可能性があります。 。」オブジェクトが到達不能になると、後続のコードはその参照と対話しなくなります。
この特定のケースでは、MimeBodyPart オブジェクトはローカル変数に格納される可能性があります。 IOUtils.copy の後続のコードが MimeBodyPart オブジェクトを参照していないため、JVM はそのオブジェクトを到達不能とみなし、ファイナライズをトリガーする可能性があります。
例とコードの変更
例が提供されています。アクティブなメソッド呼び出し中にオブジェクトがどのようにファイナライズされるかを示します。 stack.
さらに、ローカル変数ではなくフィールドに FinalizeThis オブジェクトへの参照を保持するようにコードを変更すると、ファイナライズが確認されます。
結論
ベスト プラクティスに従って、finalize() の使用を避けることをお勧めします。ただし、Java 8 では、特定の状況下で到達可能なオブジェクトをファイナライズすることが可能です。これは、コードをレビューし、オブジェクトのファイナライゼーションに関連する例外をトラブルシューティングするときに考慮する必要があります。
以上が強力に到達可能な Java オブジェクトが Java 8 で最終化されたのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。