GC roots如何判斷物件不可達

OkidoGreen發表於2020-04-05

https://blog.csdn.net/sinat_33087001/article/details/77987463

查詢記憶體中不再使用的物件

  • 引用計數法

引用計數法就是如果一個物件沒有被任何引用指向,則可視之為垃圾。這種方法的缺點就是不能檢測到環的存在。

 

  • 2.根搜尋演算法

根搜尋演算法的基本思路就是通過一系列名為”GC Roots”的物件作為起始點,從這些節點開始向下搜尋,搜尋所走過的路徑稱為引用鏈(Reference Chain),當一個物件到GC Roots沒有任何引用鏈相連時,則證明此物件是不可用的。

 

引用計數法

下面通過一段程式碼來對比說明:

?

1

2

3

4

5

6

7

8

9

10

11

public class MyObject {

    public Object ref = null;

    public static void main(String[] args) {

        MyObject myObject1 = new MyObject();

        MyObject myObject2 = new MyObject();

        myObject1.ref = myObject2;

        myObject2.ref = myObject1;

        myObject1 = null;

        myObject2 = null;

    }

}

 上述程式碼中myObject1和myObject2其實互相引用,他們的引用計數都為1,但是本身都是null,如果用引用計數法因為計數為1不會被GC回收,但他們本身為null,最終導致記憶體洩漏


如果採用的是引用計數演算法:

再回到前面程式碼GcDemo的main方法共分為6個步驟:

  • Step1:GcObject例項1的引用計數加1,例項1的引用計數=1;
  • Step2:GcObject例項2的引用計數加1,例項2的引用計數=1;
  • Step3:GcObject例項2的引用計數再加1,例項2的引用計數=2;
  • Step4:GcObject例項1的引用計數再加1,例項1的引用計數=2;

執行到Step 4,則GcObject例項1和例項2的引用計數都等於2。

接下來繼續結果圖:

  • Step5:棧幀中obj1不再指向Java堆,GcObject例項1的引用計數減1,結果為1;
  • Step6:棧幀中obj2不再指向Java堆,GcObject例項2的引用計數減1,結果為1。

到此,發現GcObject例項1和例項2的計數引用都不為0,那麼如果採用的引用計數演算法的話,那麼這兩個例項所佔的記憶體將得不到釋放,這便產生了記憶體洩露。

 


根搜尋演算法
這是目前主流的虛擬機器都是採用GC Roots Tracing演算法,比如Sun的Hotspot虛擬機器便是採用該演算法。 該演算法的核心演算法是從GC Roots物件作為起始點,利用數學中圖論知識,圖中可達物件便是存活物件,而不可達物件則是需要回收的垃圾記憶體。這裡涉及兩個概念,一是GC Roots,一是可達性。

那麼可以作為GC Roots的物件(見下圖):

  • 虛擬機器棧的棧幀的區域性變數表所引用的物件;
  • 本地方法棧的JNI所引用的物件;
  • 方法區的靜態變數和常量所引用的物件;

關於可達性的物件,便是能與GC Roots構成連通圖的物件,如下圖:


從上圖,reference1、reference2、reference3都是GC Roots,可以看出:

  • reference1-> 物件例項1;
  • reference2-> 物件例項2;
  • reference3-> 物件例項4;
  • reference3-> 物件例項4 -> 物件例項6;

可以得出物件例項1、2、4、6都具有GC Roots可達性,也就是存活物件,不能被GC回收的物件。
而對於物件例項3、5直接雖然連通,但並沒有任何一個GC Roots與之相連,這便是GC Roots不可達的物件,這就是GC需要回收的垃圾物件。

到這裡,相信大家應該能徹底明白引用計數演算法和根搜尋演算法的區別吧

再回過頭來看看最前面的例項,GcObject例項1和例項2雖然從引用計數雖然都不為0,但從根搜尋演算法來看,都是GC Roots不可達的物件。

總之,對於物件之間迴圈引用的情況,引用計數演算法,則GC無法回收這兩個物件,而根搜尋演算法則可以正確回收。

 

轉自:知乎  Gityuan  主頁https://www.zhihu.com/people/gityuan/answers

相關文章