對象生命周期中至少被GC一次後存活
Finalize調用流程:GC時,當對象變成(GC Roots)不可達時,若該對象覆蓋(重寫)了finalize方法並且未執行過finalze方法,則將其放入F-Queue隊列,由一低優先級線程執行該隊列中對象的finalize方法;否則直接將其回收。執行finalize方法完畢後,GC會再次判斷該對象是否可達,若不可達,則進行回收,否則,對象“復活”。
system.gc()並不是你調用就馬上執行的, 而是根據虛擬機的各種算法來來計算出執行垃圾回收的時間,另外,程序自動結束時不會執行垃圾回收的。其次:對象被回收時,要經過兩次標記,第一次標記,如果finalize未被重寫,或者finalize被調用過,那麽垃圾回收並不會去執行finalize,否則會執行finalize方法;第二次標記,如果對象不能在finalize中成功拯救自己,那真的就要被回收了
實例如下:
public class FinalizeEscapseGC {
public static FinalizeEscapseGC gcObject = null;
public static FinalizeEscapseGC fe = null;
public void isAlive() {
System.out.println("I am still Alive");
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize method excute");
FinalizeEscapseGC.gcObject = this;
}
public static void main(String[] args) throws InterruptedException {
gcObject = new FinalizeEscapseGC();
gcObject = null;
System.gc();//因為finalize方法被重寫了,並且還沒有被調用,所以此時會調用finalize方法
Thread.sleep(500);
if (gcObject != null) {
gcObject.isAlive();
} else {
System.out.println("gcObject is dead");
}
gcObject = null;
System.gc();//此時因為finalize方法已經被調用了,所以不會再調用;該對象會被直接回收
Thread.sleep(500);
if (gcObject != null) {
gcObject.isAlive();
} else {
System.out.println("gcObject is dead");
}
}
}
結果如下:
finalize method excute//第一次gc時調用finalize方法
I am still Alive//調用finalize後,對象被救活
gcObject is dead//第二次調用gc不再執行finalize方法,直接回收
參考鏈接:https://blog.csdn.net/h2604396739/article/details/78125305
對象生命周期中至少被GC一次後存活