了解Java 8 中的Finalize() 呼叫
從Java 7 到Java 8 的過渡中,訊息處理應用程式偶爾會遇到到異常與流關閉相關。調查顯示,對持有流的物件意外地呼叫了 Finalize(),導致其在主動讀取操作期間關閉。
最初令人費解的是,此行為可歸因於對垃圾收集的一個不太了解的方面。即使引用堆疊上存在的物件並且在活動方法呼叫期間,物件仍然可以被視為不可存取。當沒有後續程式碼存取其引用時,就會發生這種情況,使其「死亡」。
如簡化範例所示,即使在活動方法執行期間,物件也可以被最終確定並進行垃圾收集:
class FinalizeThis { @Override protected void finalize() { System.out.println("finalized!"); } void loop() { for (int i = 0; i < 1,000,000,000; i++) { // Triggering GC with System.gc() doesn't guarantee garbage collection } } public static void main(String[] args) { new FinalizeThis().loop(); } }
在此範例中,FinalizeThis 物件的參考保留在範圍內,但由於缺乏與其進一步互動而無法存取。因此,它有資格進行最終確定和隨後的垃圾回收。
在報告的情況下,MIMEBodyPart 物件可能已儲存在帶有 m_ 前綴的局部變數中,滿足潛在無法存取的條件。透過依照註解中的建議修改物件的儲存位置,終結行為停止。
值得注意的是,可以透過引入編譯指令來規避此終結問題。 -Xcomp 標誌強制方法在執行前進行編譯,允許編譯器執行可達性分析並避免不必要的終結呼叫。
以上是為什麼 Java 8 中的 Finalize() 呼叫會意外觸發流關閉?的詳細內容。更多資訊請關注PHP中文網其他相關文章!