1. 程式人生 > >對象生命周期中至少被GC一次後存活

對象生命周期中至少被GC一次後存活

class net out roo 線程 自動 isa ted 自己

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一次後存活