JEP 421: Java將要終結finalize()了!
finalize()在未來的版本中,預設情況下將被禁用,在以後的版本中它將被刪除。依賴於最終確定的庫和應用程式的維護者應該考慮遷移到其他資源管理技術,例如try-with-resources 語句和cleaners。
Java 程式能自動記憶體管理,其中 JVM 的垃圾收集器 (GC) 在不再需要物件時回收該物件使用的記憶體。但是,某些物件表示作業系統提供的資源,例如開啟的檔案描述符或本機記憶體塊。對於這樣的物件,僅僅回收物件的記憶體是不夠的;程式還必須將底層資源釋放回作業系統,通常是透過呼叫物件的close方法。如果程式在 GC 回收物件之前未能執行此操作,則釋放資源所需的資訊將丟失。作業系統仍認為正在使用的資源已洩漏。
ava 1.0 中引入的finalize()旨在幫助避免資源洩漏:一個個類可以宣告一個終結方法:protected void finalize();
該finalize方法可以執行諸如呼叫物件的close方法之類的操作。乍一看,這似乎是防止資源洩漏的有效安全網,實際上,finalize()利用垃圾收集的力量來管理非記憶體資源(Barry Hayes,收集器介面中的終結,記憶體管理國際研討會,1992)。
不幸的是,最終確定有幾個關鍵的基本缺陷:
- 不可預測的延遲——在物件變得不可訪問的那一刻和它的finalize被呼叫的那一刻之間可能會經過任意長的時間。事實上,GC 不保證任何finalize都會被呼叫。
- 不受約束的行為——finalize程式碼可以採取任何行動。特別是,它可以儲存對正在終結的物件的引用,從而復活該物件並使其再次可達。
- 始終啟用— finalize沒有明確的序號產生器制。帶有finalize的類可以對類的每個例項進行終結,無論是否需要。不能取消物件的終結,即使該物件不再需要它。
- 未指定的執行緒——finalize以任意順序在未指定的執行緒上執行。執行緒和排序都無法控制。
這些缺陷在二十多年前就被廣泛認可。它在 Java 平臺中的存在給整個生態系統帶來了負擔,因為它將所有庫和應用程式程式碼暴露在安全性、可靠性和效能風險中。它還對 JDK,特別是 GC 實現施加了持續的維護和開發成本。為了推動 Java 平臺向前發展,我們將棄用finalize以進行移除。
鑑於與最終確定相關的問題,開發人員應該使用替代技術來避免資源洩漏,即try-with-resources 和清潔器。
- Try-with-resources — Java 7 引入了try-with-resources 語句,作為對上述try-finally結構的改進。
try-with-resources 正確處理所有異常情況,避免了對finalize安全網的需要。在單個詞法範圍內開啟和關閉的任何資源都應轉換為與try-with-resources 一起使用。如果帶有finalize的類的例項只能在try-with-resources 語句中使用,則finalize可能是不必要的,可以刪除。 - Cleaner ——有些資源的生命try週期太長,無法與-with-resources很好地配合使用,因此 Java 9 引入了CleanerAPI 來幫助釋放它們。Cleaner API 允許程式為物件註冊清理操作,該操作在物件變得不可訪問後的一段時間執行。清理操作避免了finalize器的許多缺點:
但是,與終結器一樣,清理操作是由 GC 安排的,因此它們可能會受到無限延遲的影響。因此,在需要及時釋放資源的情況下,不應使用更清潔的 API。
將最終棄用java.base和java.desktop模組中的這些方法
java.lang.Object.finalize() java.lang.Enum.finalize() java.awt.Graphics.finalize() java.awt.PrintJob.finalize() java.util.concurrent.ThreadPoolExecutor.finalize() javax.imageio.spi.ServiceRegistry.finalize() javax.imageio.stream.FileCacheImageInputStream.finalize() javax.imageio.stream.FileImageInputStream.finalize() javax.imageio.stream.FileImageOutputStream.finalize() javax.imageio.stream.ImageInputStreamImpl.finalize() javax.imageio.stream.MemoryCacheImageInputStream.finalize() |
此外,我們將:
- 最終棄用java.lang.Runtime.runFinalization()和java.lang.System.runFinalization(). 這些方法沒有最終確定就沒有任何意義。
- 棄用模組介面中的getObjectPendingFinalizationCount()方法
相關文章
- C# Dispose 和 Finalize 要點C#
- 阿韋的2018年總結:我終於要出書了 | 掘金年度徵文
- Java中final、finally、finalize的區別Java
- Java中final,finally,finalize的區別Java
- Java“虛擬執行緒”被提交到JEP草案Java執行緒
- 裝修終於結束了
- 應該要PHP轉Java了。。。PHPJava
- 全新標準OpenXR出臺,VRAR行業“碎片化”亂象總算要終結了VR行業
- finalize方法
- 【日記】夢到兄長要給鱷魚換牙齒……(421 字)
- 【Java面試題系列】:Java中final finally finalize的區別Java面試題
- JEP 428:針對JDK 19提出的結構化併發JDK
- 《鳴潮》首測即將開啟,庫洛的二次元世界終於要來了!二次元
- 牛客網刷題(純java題型 421~450題)Java
- 幹了 2 年多 Java 外包,終於脫離了!Java
- Figure AI把「終結者」造出來了AI
- 死磕 java集合之終結篇Java
- 玩家苦等多年,《消逝的光芒2》終於要來了
- final和finalize
- final:finalize:finally:
- JEP 419:JDK18將無需JNI呼叫JVM外部程式和資料JDKJVM
- “終極測試”的《幻塔》,終於確定了開放世界要怎麼做
- FIN421 Econometrics for FinanceNaN
- Java面試通關要點彙總集【終極版】Java面試
- java之Hibernate面試要點總結Java面試
- 與 Rust 勾心鬥角 · 終於要標註生命週期了Rust
- Java 21 終於對這些功能動刀了!!Java
- 『Java 語法基礎』final、finalize 和 finally 的不同之處Java
- 20241027LeetCode421周賽LeetCode
- Effective Java 避免使用終結方法和清空方法Java
- WKWebView終究要入坑WebView
- 買了課程大半年,今天終於可以交作業了,因為明天要上戰場了。
- Linux 中的軟盤走向終結了嗎?Torvalds 將軟盤的驅動標記為“孤兒”Linux
- final、finally、finalize的理解
- 你要的 Helm Chart 應用金絲雀釋出終於來了!
- 終於有人把Java記憶體模型說清楚了Java記憶體模型
- 終於可以愉快的擼Java非同步程式碼了!Java非同步
- java中方法的終結者(final關鍵字)Java