【Java】finalize用法

  finalize()是Object類裏的protected類型的方法,子類(所有類都是Object的子類)可以通過覆蓋這個方法來實現回收前的資源清理工作。和這個方法相關的流程如下所述。

    1 Java虛擬機一旦通過剛纔提到的“根搜索算法”判斷出某對象處於可回收狀態時,會判斷該對象是否重寫了Object類的finalize方法,如果沒,則直接回收。

    2 如重寫過finalize方法,而且未執行過該方法,則把該對象其放入F-Queue隊列,另個線程會定時遍歷F-Queue隊列,並執行該隊列中各對象的finalize方法。

    3 finalize方法執行完畢後,GC會再次判斷該對象是否可被回收,如果可以,則進行回收,如果此時該對象上有強引用,則該對象“復活”,即處於“不可回收狀態”。

  通過下面的FinalizeDemo.java,我們來演示下通過finalize方法復活對象的做法。

1    public class FinalizeDemo {
2        static FinalizeDemo obj = null;  
3        //重寫Object裏的finalize方法  
4        protected void finalize() throws Throwable {  
5            System.out.println("In finalize()");  
6            obj = this; //給obj加個強引用  
7        }      
8        public static void main(String[] args) throws InterruptedException {  
9            obj = new FinalizeDemo();  
10            obj = null; //去掉強引用  
11            System.gc(); //垃圾回收
12            //sleep 1秒,以便垃圾回收線程清理obj對象 
13            Thread.sleep(1000);
14            if (null != obj) { //在finalize方法復活  
15                System.out.println("Still alive.");  
16            } else {  
17                System.out.println("Not alive.");  
18            } 
19        }  
20    }

    在main函數裏的第9行裏,我們給第2行定義的obj對象分配了一塊內存空間,並在第10行去掉obj所指空間的強引用,在第11行,通過System.gc方法啓動了垃圾回收機制。

    這時,由於obj所指向的對象上沒有強引用,所以這塊對象可以被回收,在回收前,是會執行其中的finalize方法。

    在第4行重寫的finalize方法裏,我們給obj對象加了一個強引用,這樣的話,在finalize方法被執行後,obj對象就不符合被回收的條件了,所以在第14行的if…else判斷裏,走第15行的流程,輸出“still alive.”這句話。

    不過,由於垃圾回收和遍歷F-Queue隊列不是同一個線程,所以一旦重寫了這個方法,就有可能導致對象被延遲迴收,如果這個方法再被放入錯誤的代碼,就極有可能導致該對象無法回收。

    所以回到本文開始的兩個問題。

    第一,finalize方法幹嘛的?

    在其中可以編寫對象被回收時的動作,具體的流程大家可以按本文給出的意思說一遍。

    第二,你有沒有重寫過這個方法?

    由於重寫finalize不當,會導致該對象無法回收,所以在項目裏,我們一般不重寫該方法,而會採用Object類自帶的空的finalize方法。

 

轉:https://www.cnblogs.com/JavaArchitect/p/14290452.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章