淺談兩個相互引用的對象是否會被GC回收

兩個相互引用的對象會被GC垃圾回收嗎?答案應該是不會!只要對象、屬性等存在被引用,GC都會過濾掉的,不會被回收。筆者就簡單談一談其中的原理吧。
判斷對象是否存活,能夠考慮如下方法。
一、引用計數算法
給對象添加一個引用計數器,每當有一個地方引用它時,計數器值就加1。
當引用失效時,計數器值就減1。
任什麼時候刻計數器爲0的對象就是不可能再被使用的。
可是主流的java虛擬機沒有采用引用計數算法,其中最主要的緣由就是它很難解決對象之間互相循環引用的問題。
例子:
對象A和B互相引用,但除此以外,這兩個對象再無任何引用,可是他們由於互相引用着對方,因此致使他們的引用計數都不爲0,因而引用計數算法沒法通知GC收集器回收他們。java

(代碼示例解釋什麼是循環引用)算法

class  A {
    public B bb;
}

class  B {
    public A aa;
}

public class TestGC {

    public static  void main(String[] args) {
    A a = new A();
    B b = new B();

    a.bb = b;
    b.aa = a;

    a = null;
    b = null;
    }
}

在上面的代碼示例中,假設咱們有兩個類分別是A和B,A類中有一個字段是B類的類型,B類中有一個字段是A類類型,如今分別new一個A類對象和new一個B類對象,此時引用a指向剛new出來的A類對象,引用b指向剛new出來的B類對象,而後將兩個類中的字段互相引用一下,這樣即便下面進行a = null和b = null,可是A類對象仍然被B類對象中的字段引用着,儘管如今A類和B類獨享都已經訪問不到了,可是引用計數卻都不爲0.
二、可達性分析算法(主流算法)
主流的實現中,都是經過可達性分析來斷定對象是否存活。
算法的基本思想:經過一系列的被稱爲「gc roots」的對象做爲起始點,從這些節點開始向下搜索,搜索所走過的路徑稱爲引用鏈,當一個對象到「gc roots」沒有任何引用鏈相連時,則證實此對象是不可用的。
能夠做爲「gc roots」的對象
(1)虛擬機棧(棧針中的局部變量表)中引用的對象
(2)方法區中類靜態屬性引用的對象。
(3)方法區中常量引用的對象
(4)本地方法棧中JNI引用的對象。編程

以上就是兩個驗證兩個相互引用的對象是否會被GC垃圾回收的方法,但願對正在編程道路上努力的同窗們有所幫助!code

相關文章
相關標籤/搜索