1. 程式人生 > >深入理解java虛擬機器閱讀筆記(二)物件是否存活與垃圾收集演算法

深入理解java虛擬機器閱讀筆記(二)物件是否存活與垃圾收集演算法

1.1  判斷物件是否存活

1.1.1  引用計數演算法:給每個物件新增一個引用計數器,當一個地方引用此物件時,該計數器值+1;當引用失效時,該計數器值-1;當此物件沒有被引用時,該計數器的值為0。雖然此演算法實現簡單,效率高,但是很難解決兩個物件之間相互迴圈引用的問題。

1.1.2  可達性分析演算法:通過一系列稱為"GC Roots"的物件作為起始點,從這些節點開始向下查詢,查詢走過的路徑稱為引用鏈,當一個物件到"GC Roots"之間沒有任何引用鏈相連時,說明此物件不可用。可以作為GC Roots 的物件有虛擬機器棧中引用的物件、方法區中靜態屬性引用的物件、方法區常量引用的物件和Native方法引用的物件。

1.2  垃圾收集演算法

1.2.1  標記-清除演算法:首先標記出需要回收的物件,然後統一回收所有標記的物件。此收集演算法的不足之處:回收效率不高,清除時會產生大量碎片,不容易分配大物件。

1.2.2  複製演算法:將可用容量劃分為相等的兩塊,每次只使用其中的一塊,當這塊記憶體用完了,將存活的物件複製到另一塊,然後把之前的記憶體空間清理掉。雖然效率高,但是浪費資源。商用虛擬機器將新生代按8:1:1分為Eden空間:From Survior空間:To Survivor空間,每次只使用90%的空間,將存活的物件複製到To Survivor空間,清理掉之前的90%空間,遇到多餘的存活物件,直接放到老年代。

1.2.3  標記-整理演算法:標記和之前一樣,整理時先讓所有存活物件向一端移動,清理掉端邊界以外的記憶體。

1.2.4  分代收集演算法:首先將java堆分為新生代和老年代,新生代每次垃圾收集時有大量物件死亡,因此採用複製演算法進行垃圾收集,老年代中物件存活率高,則採用“標記-清理”或“標記-整理”演算法收集。