文章出處
文章列表
一、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
文章列表
全站熱搜