首頁 > Java > 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 writer (MIMEWriter),MIME 正文部分(MIMEBodyPart),MIME 正文部分(MIMEBodyPartPartInflaterInputStream

)。 MIMEBodyPart 擴展了 HTTPMessage,其中包含一個用於關閉底層流的 close() 方法。此外,HTTPMessage 有一個 Finalize() 方法,如果流仍然打開,它會嘗試呼叫 close()。

    事件序列:
  1. MIMEWriter 為附件部分寫入標頭。
  2. MIMEBodyPart 使用 IOUtil.copy 寫入正文內容,它將區塊從輸入流複製到輸出
IOUtil.copy 嘗試讀取一個 chunk,但遇到關閉的流,觸發異常。

原因:

The當 IOUtil.copy 主動運作時,終結器執行緒會事先呼叫 MIMEBodyPart.finalize() 方法。 Java 8 引入了垃圾收集優化,允許物件最終確定,即使它們仍然被局部變數或活動方法呼叫引用。

MIMEBodyPart 物件確實可以從 MIMEBodyPart.writeBodyPartContent 的堆疊幀訪問,這意味著JVM 不應嘗試完成它。但是,由於 IOUtil.copy 循環中對 MIMEBodyPart 的引用未被主動使用,因此它變得無法訪問並且有資格進行垃圾收集和終結。

後果:

過早完成可能會導致不正確的行為和潛在數據

解決方案:

建議的方法是重新存取本機程式庫並消除使用Finalize() 方法。由於 Java Mail 的 MIME 庫沒有出現該問題,因此它可以作為替代方案。

替代猜想:

另一個可能的解釋涉及 InflaterInputStream。如果在 InflaterInputStream 內的不可中斷操作期間呼叫 MIMEBodyPart.finalize() 方法,則可能會中斷流並觸發異常。然而,這個假設還需要進一步研究。

以上是為什麼我的強可達 Java 8 物件過早完成?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板