即使在可達性分析算法中不可達的對象,也并不是“非死不可”。
要宣告一個對象死亡,至少要經過兩次标記過程:如果對象在進行可達性分析後發現沒有與GC Roots相連接配接的引用鍊,那它将會被第一次标記并且進行一次篩選,篩選的條件是此對象是否有必要執行finalize()方法。當對象沒有覆寫finalize()方法,或者finalize()方法已經被虛拟機調用過,虛拟機将這兩種情況都視為“沒有必要執行”。
如果這個對象被判定為有必要執行finalize()方法,那麼這個對象将會放置在一個叫做F-Queue的隊列之中,并在稍後由一個由虛拟機自動建立的、低優先級的Finalizer線程去執行它。這裡所謂的“執行”是指虛拟機會觸發這個方法,但并不承諾會等待它運作結束,這樣做的原因是,如果一個對象在finalize()中執行緩慢,或者發生了死循環,将可能會導緻F-Queue隊列中其他對象永久處于等待,甚至導緻整個記憶體回收系統崩潰。finalize()方法是對象逃脫死亡命運的最後一次機會,稍後GC将對F-Queue中的對象進行第二次小規模的标記,如果對象在finalize()中成功拯救自己----隻要重新與引用鍊上的任何一個對象建立關聯即可,譬如把自己(this關鍵字)指派給某個類變量或者對象的成員變量,那在第二次标記時它将被移除出“即将回收”的集合;如果對象這時候沒有逃脫,那基本上它就真的被回收了。
運作結果: