本篇文章簡單介紹一下各個gc算法的原理和優缺點
GC Root
GC roots are not objects in themselves but are instead references to objects.
.NET中可以當作GC Root的對象有如下幾種:
1、全局變量
2、靜態變量
3、棧上的所有局部變量(JIT)
4、棧上傳入的參數變量
5、寄存器中的變量
在Java中,可以當做GC Root的對象有以下幾種:
1、虛擬機(JVM)棧中的引用的對象
2、方法區中的類靜態屬性引用的對象
3、方法區中的常量引用的對象(主要指聲明為final的常量值)
4、本地方法棧中JNI的引用的對象
標記清除法
原理:從GC Root開始遞歸,對可能引用的對象進行標記,沒有標記的作為垃圾被回收
步驟:遍歷並標記對象->回收死亡對象,清除存活對象的標記
缺點:
1.清除階段還需要對大量死亡對象進行掃描,死亡對象多的話會相當耗時
2.清理出來的內存空間不連續
標記整理法
原理:從GC Root開始遞歸,對可能引用的對象進行標記,之后移動所有存活的對象,且按照內存地址次序依次排列,然后將末端內存地址以后的內存全部回收
步驟:遍歷並標記對象->整理存活對象->回收
缺點:效率低
復制清除法
原理:遍歷GC Root引用的對象,復制到另外的空間,並遞歸地對復制對象引用的對象進行復制,之后清除舊空間
步驟:遞歸復制->廢棄舊空間
缺點:
1.復制開銷大,存活對象多耗時大
2.浪費一半的內存
引用計數法
原理:為每個對象保存引用計數,引用增減時更新計數
步驟:不需要掃描,對計數0的對象進行垃圾回收
缺點:
1.無法釋放循環引用的對象
循環引用
1 A a = new A(); 2 B b = new B(); 3 C c = new C(); 4 A.b = b; 5 B.c = c; 6 C.a = a;
2.引用計數不能遺漏
3.不適合並行處理
分代搜集法
原理:對分配時間短的對象進行清理
比如Net,將內存中的對象分為了三代,每執行N次0代的回收,才會執行一次1代的回收,而每執行N次1代的回收,才會執行一次2代的回收。當某個對象實例在GC執行時被發現仍然在被使用,它將被移動到下一個代中上。
而在mono 中是分2代
各平台GC算法
關於Mono ,集成的是開源項目BOEHM ,BOEHM算法采用標記清除法