java finalize逃脱_JVM【第十三回】:【Java对象存活------finalize()方法】
在根搜索算法中不可達的對象,也并非是“非死不可”的,這個時候他們暫時處于"緩刑"階段,要真正宣告一個對象死亡,至少要經歷兩次標記過程:如果對象在進行根搜索后發現沒有與GC Roots相連接的引用鏈,那它將會被第一次標記并且進行一次篩選,篩選的條件是對象是否有必要執行finalize()方法。當對象沒有覆蓋finalize()方法,或者finalize()方法已經被虛擬機調用過,虛擬機將這兩種情況都視為“沒有必要執行”。
如果這個對象被判定為有必要執行finalize()方法,那么這個對象將會被放置在一個名為F-Queue的隊列之中,并在稍后由一條由虛擬機自動簡歷的、低優先級的Finalizer線程去執行。這里所謂的“執行”是指虛擬機會觸發這個方法,但并不承諾會等待它運行結束。這樣做的原因是,如果一個對象在finalize()方法中執行緩慢,或者發生了死循環,將很可能導致F-Queue隊列中的其他對象永久處于等待狀態,甚至導致整個內存回收系統崩潰。finalize()方法是對象逃脫死亡命運的最后一次機會。稍后GC將對F-Queue中的對象進行第二次小規模的標記,如果對象要在finalize()中成功拯救自己——只要重新與引用鏈上的任何一個對象建立關聯即可,那在第二次標記時它將被移除出“即將回收”的集合;如果對象這時候還沒有逃脫,那它就真的離死不遠了。
如下代碼中我們可以看到一個對象的finalize()被執行,但是它仍然可以存活。
package?gc;
/**
*?對象自我拯救的演示
*?@author?Madison
*?@date?2014-7-12
*?注:此代碼演示了兩點:
*?1、對象可以在被GC時自我拯救
*?2、這種自救的機會只有一次,因為一個對象的finalize()方法最多只會被系統自動調用一次
*/
public?class?FinalizeEscapeGC
{
private?static?FinalizeEscapeGC?SAVE_HOOK?=?null;
public?void?isAlive()
{
System.out.println("yes,?i?am?still?alive!");
}
public?static?void?main(String[]?args)?throws?Throwable
{
SAVE_HOOK?=?new?FinalizeEscapeGC();
//對象第一次成功拯救自己
SAVE_HOOK?=?null;
System.gc();
//因為finalize方法優先級很低,暫停0.5秒,以等待它
Thread.sleep(500);
if(SAVE_HOOK?!=?null)
SAVE_HOOK.isAlive();
else
System.out.println("no,?i?am?dead!");
//下面這段代碼與上面的完全相同,但是這次自救卻失敗了
SAVE_HOOK?=?null;
System.gc();
//因為finalize方法優先級很低,暫停0.5秒,以等待它
Thread.sleep(500);
if(SAVE_HOOK?!=?null)
SAVE_HOOK.isAlive();
else
System.out.println("no,?i?am?dead!");
}
@Override
protected?void?finalize()?throws?Throwable
{
super.finalize();
System.out.println("finalize?method?executed!");
FinalizeEscapeGC.SAVE_HOOK?=?this;
}
}
運行結果:
finalize method executed!
yes, i am still alive!
no, i am dead!
從代碼的運行結果可以看到,SAVE_HOOK對象的finalize()方法確實被GC收集器觸發過,并且在被收集前成功逃脫了。另外一個值得注意的地方就是,代碼中有兩段完全一樣的代碼片段,執行結果卻是一次逃脫成功,一次失敗,這是因為任何一個對象的finalize()方法都只會被系統自動調用一次,如果對象面臨下一次回收,它的finalize()方法不會被再次窒息感,因此第二段代碼的自救行動失敗了。
友情提醒:大家盡量避免使用finalize()方法,因為它的運行代價高昂,不確定性大,無法保證各個對象的調用順序。finalize()能做的所有工作,使用try-finally或者其他方式都可以做得更好、更及時。
欲知后事如何,且聽下回分解
總結
以上是生活随笔為你收集整理的java finalize逃脱_JVM【第十三回】:【Java对象存活------finalize()方法】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019年清华同方台式机如何
- 下一篇: java ftp 关闭连接_java -