文章出處

一、finalize與GC                            

  在GC第一次進行可達性分析時會將不可達而且該對象所屬類重寫finalize方法finalize方法重未被執行過的對象追加到F-Queue當中,然后JVM會自動開啟一個低優先級的守護線程Finalizer執行F-Queue中元素的finalize方法。此時可通過finalize方法重新將不可達對象與引用鏈關聯起來,那么在GC第二次進行可達性分析時,則可逃離被回收的名單。

class FinalizeEscapeGC{
  public static FinalizeEscapeGC SAVE_HOOK = null;
  public void isAlive(){
     System.out.println("yes, i am still alive;");
  }

  @override
  protected void finalize() throws Throwable{
    super.finalize();
    System.out.println("finalize method executed!");
    FinalizeEscapeGC.SAVE_HOOK = this;
  }

  public static void main(String[] args) throws Throwable{
      SAVE_HOOK = new FinalizeEscapeGC();

      SAVE_HOOK = null;
      System.gc();
      Thread.sleep(500);
      if (SAVE_HOOK == null) SAVE_HOOK.isAlive();
      else System.out.println("no, i am dead :(");
            
      SAVE_HOOK = null;
      System.gc();
      Thread.sleep(500);
      if (SAVE_HOOK == null) SAVE_HOOK.isAlive();
      else System.out.println("no, i am dead :(");
  }
}

第一次成功通過finalize方法成功逃脫回收名單,但第二次因為finalize方法之前已經被調用過,因此不會在執行finalize方法,所以注定被回收了。

注意:finalizer線程執行每個對象的finalize方法時是非阻塞的,因此并不保證GC進行第二次標記時finalize方法執行完成。

 

二、在finalize方法中釋放資源?                   

  說起finalize方法大家就會聯想到析構函數,并希望像析構函數那樣使用,然后什么資源釋放收尾等工作都放在finalize方法中。其實這只是讓C/C++程序員更容易轉向Java陣營的妥協而已,大家最好還是忘記有這一個方法吧,通過try-catch-finally釋放資源更有效。

 

  尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/4269086.html  ^_^肥仔John

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()