1. 程式人生 > >【Java虛擬機器】判斷物件是否存活的演算法

【Java虛擬機器】判斷物件是否存活的演算法

判斷物件是否存活的演算法

判斷物件是否存活的演算法

引用計數演算法

引用計數演算法是這樣的:給物件中新增一個引用計數器,每當一個地方引用時,計數器值就加1;當引用失效時,計數器值就減1;任何時刻計數器為0的物件就是不可能再被使用的。

主流的Java虛擬機器裡面沒有選用引用計數器演算法來管理記憶體,其中最主要的原因就是它很難解決物件之間迴圈引用的問題。

舉個例子:

public class ReferenceCountingGC
{ public Object instance = null; private static final int _1MB = 1024 * 1024; private byte[] bigSize = new byte[2 * _1MB]; public static void main(String[] args) { ReferenceCountingGC objA = new ReferenceCountingGC(); ReferenceCountingGC objB = new ReferenceCountingGC(); objA.instance =
objB; objB.instance = objA; objA = null; objB = null; System.gc(); } }

objA和objB都有欄位instance,賦值objA.instance = objB以及objB.instance = objA,除此之外,這兩個物件再無任何引用,實際上這兩個物件已經不可能再被訪問,但是它們因為互相引用著對方,導致它們的引用計數都不為0,於是引用技術演算法無法通知GC收集器回收它們。

可達性分析演算法

可達性分析演算法的基本思想就是通過一系列的成為“GC Roots”的物件作為起始點,從這些起始點開始向下搜尋,搜尋所經過的路徑稱為引用鏈,當一個物件到GC Roots沒有任何引用鏈相連(用圖論的話來說,就是從GC Roots到這個物件不可達)時,則證明此物件是不可用的。

舉個例子:
可達性分析演算法判定物件是否可回收
如上圖,物件object5、object6、object7雖然互相有關聯,但是它們到GC Roots是不可達的,所以它們將會被判定為是可回收的物件。

在Java語言中,可作為GC Roots的物件包括下面幾種:

  • 虛擬機器棧中引用的物件
  • 本地方法棧JNI(即一般說的Native方法)所引用的物件
  • 方法區中類靜態屬性引用的物件
  • 方法區中常量引用的物件

參考

  1. 深入理解Java虛擬機器[書籍]