好程式設計師Java學習路線分享finalize()方法詳解
好程式設計師 Java 學習路線分享 finalize() 方法詳解 ,前言,finalize() 是 Object 的 protected 方法,子類可以覆蓋該方法以實現資源清理工作, GC 在回收物件之前呼叫該方法。。
finalize 的作用
(1)finalize() 與 C++ 中的解構函式不是對應的。 C++ 中的解構函式呼叫的時機是確定的(物件離開作用域或 delete 掉),但 Java 中的 finalize 的呼叫具有不確定性
(2) 不建議用 finalize 方法完成“非記憶體資源”的清理工作,但建議用於:① 清理本地物件 ( 透過 JNI 建立的物件 ) ;② 作為確保某些非記憶體資源 ( 如 Socket 、檔案等 ) 釋放的一個補充:在 finalize 方法中顯式呼叫其他資源釋放方法。其原因可見下文 [finalize 的問題
finalize 的問題
(1) 一些與 finalize 相關的方法,由於一些致命的缺陷,已經被廢棄了,如 System.runFinalizersOnExit() 方法、 Runtime.runFinalizersOnExit() 方法
(2)System.gc() 與 System.runFinalization() 方法增加了 finalize 方法執行的機會,但不可盲目依賴它們
(3)Java 語言規範並不保證 finalize 方法會被及時地執行、而且根本不會保證它們會被執行
(4)finalize 方法可能會帶來效能問題。因為 JVM 通常在單獨的低優先順序執行緒中完成 finalize 的執行
(5) 物件再生問題: finalize 方法中,可將待回收物件賦值給 GC Roots 可達的物件引用,從而達到物件再生的目的
(6)finalize 方法至多由 GC 執行一次 ( 使用者當然可以手動呼叫物件的 finalize 方法,但並不影響 GC 對 finalize 的行為 )
finalize 的執行過程 ( 生命週期 )
(1) 首先,大致描述一下 finalize 流程:當物件變成 (GC Roots) 不可達時, GC 會判斷該物件是否覆蓋了 finalize 方法,若未覆蓋,則直接將其回收。否則,若物件未執行過 finalize 方法,將其放入 F-Queue 佇列,由一低優先順序執行緒執行該佇列中物件的 finalize 方法。執行 finalize 方法完畢後, GC 會再次判斷該物件是否可達,若不可達,則進行回收,否則,物件“復活”。
(2) 具體的 finalize 流程:
物件可由兩種狀態,涉及到兩類狀態空間,一是終結狀態空間 F = {unfinalized, finalizable, finalized} ;二是可達狀態空間 R = {reachable, finalizer-reachable, unreachable} 。各狀態含義如下:
unfinalized: 新建物件會先進入此狀態, GC 並未準備執行其 finalize 方法,因為該物件是可達的
finalizable: 表示 GC 可對該物件執行 finalize 方法, GC 已檢測到該物件不可達。正如前面所述, GC 透過 F-Queue 佇列和一專用執行緒完成 finalize 的執行
finalized: 表示 GC 已經對該物件執行過 finalize 方法
reachable: 表示 GC Roots 引用可達
finalizer-reachable(f-reachable) :表示不是 reachable ,但可透過某個 finalizable 物件可達
unreachable :物件不可透過上面兩種途徑可達
(1) 新建物件首先處於 [reachable, unfinalized] 狀態 (A)
(2) 隨著程式的執行,一些引用關係會消失,導致狀態變遷,從 reachable 狀態變遷到 f-reachable(B, C, D) 或 unreachable(E, F) 狀態
(3) 若 JVM 檢測到處於 unfinalized 狀態的物件變成 f-reachable 或 unreachable , JVM 會將其標記為 finalizable 狀態 (G,H) 。若物件原處於 [unreachable, unfinalized] 狀態,則同時將其標記為 f-reachable(H) 。
(4) 在某個時刻, JVM 取出某個 finalizable 物件,將其標記為 finalized 並在某個執行緒中執行其 finalize 方法。由於是在活動執行緒中引用了該物件,該物件將變遷到 (reachable, finalized) 狀態 (K 或 J) 。該動作將影響某些其他物件從 f-reachable 狀態重新回到 reachable 狀態 (L, M, N)
(5) 處於 finalizable 狀態的物件不能同時是 unreahable 的,由第 4 點可知,將物件 finalizable 物件標記為 finalized 時會由某個執行緒執行該物件的 finalize 方法,致使其變成 reachable 。這也是圖中只有八個狀態點的原因
(6) 程式設計師手動呼叫 finalize 方法並不會影響到上述內部標記的變化,因此 JVM 只會至多呼叫 finalize 一次,即使該物件“復活”也是如此。程式設計師手動呼叫多少次不影響 JVM 的行為
(7) 若 JVM 檢測到 finalized 狀態的物件變成 unreachable ,回收其記憶體 (I)
(8) 若物件並未覆蓋 finalize 方法, JVM 會進行最佳化,直接回收物件( O )
(9) 注: System.runFinalizersOnExit() 等方法可以使物件即使處於 reachable 狀態, JVM 仍對其執行 finalize 方法
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2653048/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師Java學習路線分享Java-String常用方法程式設計師Java
- 好程式設計師Java學習路線分享SpringCloud程式設計師JavaSpringGCCloud
- 好程式設計師web前端學習路線分享Jsonp詳解程式設計師Web前端JSON
- 好程式設計師大資料學習路線分享AWK詳解程式設計師大資料
- 好程式設計師雲端計算學習路線分享LVM管理詳解程式設計師LVM
- 好程式設計師Java學習路線分享mybatis對映程式設計師JavaMyBatis
- 好程式設計師Java學習路線分享Java框架怎麼搭建程式設計師Java框架
- 好程式設計師Java學習路線分享原生Ajax的使用程式設計師Java
- 好程式設計師Java學習路線分享JVM相關概念程式設計師JavaJVM
- 好程式設計師Java學習路線分享MyBatis之Spring整合程式設計師JavaMyBatisSpring
- 好程式設計師Java學習路線分享Redis快速入門程式設計師JavaRedis
- 好程式設計師Java學習路線分享MyBatis之基本使用程式設計師JavaMyBatis
- 好程式設計師Java學習路線分享maven是什麼程式設計師JavaMaven
- 好程式設計師Java學習路線分享SpringMVC之MVC概述程式設計師JavaSpringMVC
- 好程式設計師Java學習路線分享5分鐘瞭解計數排序程式設計師Java排序
- 好程式設計師Java學習路線分享Java中的位移運算程式設計師Java
- 好程式設計師web前端學習路線分享滾動穿透方法程式設計師Web前端穿透
- 好程式設計師Java學習路線分享三大特性之多型程式設計師Java多型
- 好程式設計師Java學習路線分享Dubbo架構介紹程式設計師Java架構
- 好程式設計師Java學習路線分享多執行緒概念程式設計師Java執行緒
- 好程式設計師Java學習路線分享MySQL目錄結構程式設計師JavaMySql
- 好程式設計師Java學習路線之集程式設計師Java
- 好程式設計師Java學習路線JSP物件程式設計師JavaJS物件
- 好程式設計師Java學習路線分享5分鐘瞭解基數排序程式設計師Java排序
- 好程式設計師Java學習路線分享Java弱引用的理解與使用程式設計師Java
- 好程式設計師Java學習路線分享Java案例-封裝JDBC工具類程式設計師Java封裝JDBC
- 好程式設計師Java學習路線分享怎麼理解Java物件導向程式設計師Java物件
- 好程式設計師Java學習路線分享SpringMVC之請求和響應程式設計師JavaSpringMVC
- 好程式設計師Java學習路線分享如何處理中文引數程式設計師Java
- 好程式設計師Java學習路線分享MyBatis之關聯查詢程式設計師JavaMyBatis
- 好程式設計師Java學習路線分享JVM類載入機制程式設計師JavaJVM
- 好程式設計師Java學習路線分享Spring常見面試題程式設計師JavaSpring面試題
- 好程式設計師大資料學習路線分享MAPREDUCE程式設計師大資料
- 好程式設計師大資料學習路線分享SparkSQl程式設計師大資料SparkSQL
- 好程式設計師大資料學習路線分享Hbase指令學習程式設計師大資料
- 好程式設計師Java學習路線分享實戰Tomcat效能最佳化程式設計師JavaTomcat
- 好程式設計師Java學習路線分享氣泡排序及最佳化程式設計師Java排序
- 好程式設計師Java學習路線分享Spring建立Bean的3種方式程式設計師JavaSpringBean