html
本篇文章简单介绍一下各个gc算法的原理和优缺点c++
GC roots are not objects in themselves but are instead references to objects.程序员
.NET中能够看成GC Root的对象有以下几种:算法
一、全局变量spa
二、静态变量code
三、栈上的全部局部变量(JIT)htm
四、栈上传入的参数变量对象
五、寄存器中的变量blog
在Java中,能够当作GC Root的对象有如下几种:递归
一、虚拟机(JVM)栈中的引用的对象
二、方法区中的类静态属性引用的对象
三、方法区中的常量引用的对象(主要指声明为final的常量值)
四、本地方法栈中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代
关于Mono ,集成的是开源项目BOEHM ,BOEHM算法采用标记清除法