Java finalize()的使用
Java finalize()
轉載地址:java finalize方法總結、GC執(zhí)行finalize的過程 - ScaleZ - 博客園 (cnblogs.com)
finalize()介紹
finalize()是Object的protected方法,子類可以覆蓋該方法以實現(xiàn)資源清理工作,GC在回收對象之前調用該方法,但Java中的finalize的調用具有不確定性。
finalize()調用生命周期
(1) 首先,大致描述一下finalize流程:當對象變成(GC Roots)不可達時,GC會判斷該對象是否覆蓋了finalize方法,若未覆蓋,則直接將其回收。否則,若對象未執(zhí)行過finalize方法,將其放入F-Queue隊列,由一低優(yōu)先級線程執(zhí)行該隊列中對象的finalize方法。執(zhí)行finalize方法完畢后,GC會再次判斷該對象是否可達,若不可達,則進行回收,否則,對象“復活”。
(2) 具體的finalize流程:
對象可由兩種狀態(tài),涉及到兩類狀態(tài)空間,一是終結狀態(tài)空間 F = {unfinalized, finalizable, finalized};二是可達狀態(tài)空間 R = {reachable, finalizer-reachable, unreachable}。各狀態(tài)含義如下:
- unfinalized: 新建對象會先進入此狀態(tài),GC并未準備執(zhí)行其finalize方法,因為該對象是可達的
- finalizable: 表示GC可對該對象執(zhí)行finalize方法,GC已檢測到該對象不可達。正如前面所述,GC通過F-Queue隊列和一專用線程完成finalize的執(zhí)行
- finalized: 表示GC已經(jīng)對該對象執(zhí)行過finalize方法
- reachable: 表示GC Roots引用可達
- finalizer-reachable(f-reachable):表示不是reachable,但可通過某個finalizable對象可達
- unreachable:對象不可通過上面兩種途徑可達
狀態(tài)變遷圖:
變遷說明:
代碼示例
評論區(qū)的老哥在示例代碼加了注釋,這邊直接復制過來。
public class GC { public static GC SAVE_HOOK = null; public static void main(String[] args) throws InterruptedException {// 新建對象,因為SAVE_HOOK指向這個對象,對象此時的狀態(tài)是(reachable,unfinalized)SAVE_HOOK = new GC(); //將SAVE_HOOK設置成null,此時剛才創(chuàng)建的對象就不可達了,因為沒有句柄再指向它了,對象此時狀態(tài)是(unreachable,unfinalized)SAVE_HOOK = null; //強制系統(tǒng)執(zhí)行垃圾回收,系統(tǒng)發(fā)現(xiàn)剛才創(chuàng)建的對象處于unreachable狀態(tài),并檢測到這個對象的類覆蓋了finalize方法,因此把這個對象放入F-Queue隊列,由低優(yōu)先級線程執(zhí)行它的finalize方法,此時對象的狀態(tài)變成(unreachable, finalizable)或者是(finalizer-reachable,finalizable)System.gc(); // sleep,目的是給低優(yōu)先級線程從F-Queue隊列取出對象并執(zhí)行其finalize方法提供機會。在執(zhí)行完對象的finalize方法中的super.finalize()時,對象的狀態(tài)變成(unreachable,finalized)狀態(tài),但接下來在finalize方法中又執(zhí)行了SAVE_HOOK = this;這句話,又有句柄指向這個對象了,對象又可達了。因此對象的狀態(tài)又變成了(reachable, finalized)狀態(tài)。Thread.sleep(500); // 這里樓主說對象處于(reachable,finalized)狀態(tài)應該是合理的。對象的finalized方法被執(zhí)行了,因此是finalized狀態(tài)。又因為在finalize方法是執(zhí)行了SAVE_HOOK=this這句話,本來是unreachable的對象,又變成reachable了。 if (null != SAVE_HOOK) { //此時對象應該處于(reachable, finalized)狀態(tài) // 這句話會輸出,注意對象由unreachable,經(jīng)過finalize復活了。System.out.println("Yes , I am still alive"); } else { System.out.println("No , I am dead"); } // 再一次將SAVE_HOOK放空,此時剛才復活的對象,狀態(tài)變成(unreachable,finalized)SAVE_HOOK = null; // 再一次強制系統(tǒng)回收垃圾,此時系統(tǒng)發(fā)現(xiàn)對象不可達,雖然覆蓋了finalize方法,但已經(jīng)執(zhí)行過了,因此直接回收。System.gc(); // 為系統(tǒng)回收垃圾提供機會Thread.sleep(500); if (null != SAVE_HOOK) { // 這句話不會輸出,因為對象已經(jīng)徹底消失了。System.out.println("Yes , I am still alive"); } else { System.out.println("No , I am dead"); } } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("execute method finalize()"); // 這句話讓對象的狀態(tài)由unreachable變成reachable,就是對象復活SAVE_HOOK = this; } }總結
以上是生活随笔為你收集整理的Java finalize()的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FutureTask使用
- 下一篇: 乐高前台电脑蓝屏了乐高前台电脑蓝屏了怎么