“在Java 8 中對強可達對象調用Finalize()”
問題:
使用Java 7 開發並最近升級到Java 8的應用程式偶爾會遇到異常,表示串流已過早關閉。調查顯示,終結器執行緒過早地對持有流的物件呼叫finalize(),從而觸發了閉包。
背景:
程式碼結構涉及MIME writer (MIMEWriter),MIME 正文部分(MIMEBodyPart),MIME 正文部分(MIMEBodyPartPartInflaterInputStream
)。 MIMEBodyPart 擴展了 HTTPMessage,其中包含一個用於關閉底層流的 close() 方法。此外,HTTPMessage 有一個 Finalize() 方法,如果流仍然打開,它會嘗試呼叫 close()。
原因:
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中文網其他相關文章!