java类中的成员成员变量赋值之后什么时候会被回收,有什么办法监听到某一个对象被回收吗
天蓬老师
天蓬老师 2017-04-18 10:50:02
0
2
659

java类中的成员成员变量赋值之后什么时候会被回收,有什么办法监听到某一个对象被回收吗

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回覆(2)
阿神

一個物件是否被回收並不是僅僅靠當前物件是否被引用這麼簡單粗暴的方法去判斷。

JVM中判斷是否回收一個物件使用的是可達性分析演算法,GC ROOT不可到達的節點都將會被標記上,一個物件如果被標記了兩次就會被回收掉。至於這個可達性分析演算法你可以自行百度一下,原理是很簡單的。

那麼用什麼方法來監聽一個物件是否被回收呢?當然用fianlize了;

請看代碼:

public class Test {
    private static Test TEST= null;
    public static void main(String args[]) {
        TEST = new Test();
        TEST = null;
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(TEST);
    }
    @Override
    public void finalize() throws Throwable {
        System.out.println("要死了要死了要死了!");
    } 
}

執行結果:

要死了要死了要死了!
null

那是不是執行了finalize後,物件就一定會被回收呢?其實不一定finalize呼叫時物件僅有一次拯救自己的機會,如下:


public class Test {
    private static Test TEST= null;
    public static void main(String args[]) {
        TEST = new Test();
        
        TEST = null;
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(TEST);
        
        TEST = null;
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(TEST);
    }
    
    @Override
    public void finalize() throws Throwable {
        System.out.println("要死了要死了要死了!");
        TEST = this;
    } 
}

執行結果如下:

要死了要死了要死了!
com.Test@1aa9f99
null

可以看到在第一次垃圾回收時,在finalize方法給了當前回收物件的新引用,避免了被回收,不過finalize方法一個物件只能呼叫一次,在第二次回收時將不會被調用了。

從上述兩個例子中我們可以得出:finalize可以監聽一個物件被回收,但是不能保證調用了finalize的物件一定會被回收,同時一個物件在第二次標記回收時是不會觸發finalize的!如果想絕對監聽一個物件是否被回收,只有在JVM裡面加入參數-XX:+PrintGCDetails分析GC日誌咯

巴扎黑

不一定什麼時候。那個物件類別的析構函數不就可以麼。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!