1. 程式人生 > >java記憶體回收之finalize()方法原理

java記憶體回收之finalize()方法原理

確認物件已死亡:1、引用計數演算法:演算法原理是 給每個物件中新增一個引用計數器,每當有地方引用它時,計數器值就加1,當引用失效時,計數器值就減1;任何時候計數器值為0的物件就是不可能再被使用的。

2、可達性分析演算法 :原理是通過一系列的稱為“GC Roots”的物件作為起始點,從這些節點開始向下搜尋,搜尋走過的路徑稱為引用鏈(reference Chain),當一個物件到GC Roots沒有任何引用鏈相連的時候,則證明該物件是不可用的。

在Java語言中,可以做GC Roots的物件的有:

1、虛擬機器 棧中引用的物件

2、方法區中類靜態屬性引用的物件

3、方法區中常量引用的物件

4、本地方法棧中JNI(一般而言的Native方法)引用的物件。

即使在可達性分析演算法中不可達的物件,也並非是“非死不可”的,真正宣告一個物件死亡,至少要經歷兩次標記過程:如果物件在進行可達性分心後沒有發現與GC roots相連線的引用鏈,那麼它會被第一標記並進行一次篩選,篩選條件是此物件是否有必要執行finalize()方法,當物件沒有覆蓋finalize()方法,或者finalize()方法已經被虛擬機器呼叫過(任何一個物件的finalize()方法都只會 被系統自動呼叫一次),虛擬機器將這兩種情況視為”沒有必要執行“。則該物件基本上就真的被回收了。

若該物件被判定為有必要執行finalize()方法,那麼該物件會被放置在一個叫做F-Queue的佇列中,並在稍後由一個由虛擬機器自動建立的,低優先順序的Finalizer執行緒去執行它(所謂”執行“就是觸發該方法,並不承諾會等待它執行結束)。finalize()方法是物件逃脫死亡命運德最後一次機會,稍後GC 將對F-Queue中的物件進行第二次小規模的標記,如果物件要在finalize()中拯救自己-----只要重新與引用鏈上的任何一個物件建立3關聯即可,eg:把自己(this)賦值給某個類變數或者物件的成員變數,那麼第二次標記的時候他將被移除

”即將回收“的集合;如果沒能在finalize()方法中拯救自己,那麼基本上 它就真的被回收了。 

狀態含義:

              Reachable:表示GC Roots引用可達(即有引用鏈相連)

              Finalize Reachable(F-reachable):不是Reachable,但通過某個finalizable物件可達

              Unreachable:表示該物件不可達(到GC Roots 沒有任何引用鏈相連)

              Unfinalized:GC未執行該物件的finalze()方法,該物件可達

              Finalzable:GC可以對該物件執行finalize()方法,GC檢測該物件不可達,GC通過F-Queue佇列執行finalize()方法

              Finalized:GC已經對該物件執行過finalize()方法,

 圖中A-->B:物件沒有override finalize()方法,在Unreachable狀態下就被回收了。

注:不建議使用該方法去拯救物件,執行代價高昂,不確定性很大,無法保證各個物件之間的呼叫順序。