[转]GC简介
原文链接:http://www.cnblogs.com/cposture/p/4845189.html
原文写得太好了,这里转一下。
1 GC机制
1.1 对象
从计算机的角度,装有数据的内存空间
1.2 作用
将内存垃圾的释放自动化
1.3 本质
将已经引用不到的对象视为死亡,将死亡的对象找出来并且作为垃圾进行回收
2 GC算法
2.1 跟踪回收
2.1.1 原理
从根开始扫描判断对象的生死
2.1.2 标记清除
(1)过程
-
第一次扫描:以变量或运行栈作为根,从根开始将可能被引用的对象进行标记,将没被标记的对象进行垃圾回收
-
第二次扫描:将全部对象进行扫描,对没有被标记的对象进行垃圾回收,扫描的同时还需要将存活的对象的标记去除
(2)缺点
-
处理时间与对象数量相关,在大量对象且极少存活的情况下,效率不明显
-
由复制收集解决这一问题
2.1.3 复制收集
(1)过程
-
扫描一遍:将根对象复制到新开辟的内存空间,再用复制的对象所能引用的对象进行递归复制
-
清除旧空间
(2)优缺点
-
扫描一遍就相当于标记清除的标记阶段,清除阶段开销极小
-
cache局部性,复制收集按照引用将关联的对象复制到新空间,在内存空间里距离较近,效率会提高
-
在存活对象大比列存在的情况下,复制对象的开销会加大
2.2 引用计数
2.2.1 原理
当对象引用发生变化时,利用引用计数更新对象的状态,判断对象的生死
2.2.2 引用计数
(1)过程
在对象内部保持一个对该对象的引用计数,当引用发生增减时进行更新
(2)优缺点
-
能够做到立即释放垃圾,中断时间短
-
无法释放循环引用的对象
-
在并行环境下,需要对计数操作进行加锁互斥,开销较大
2.3 跟踪回收和引用计数的结合
2.3.1 分代回收
(1)原理
大部分对象在短时间里会成为垃圾,而经过一定时间仍然存活下来的往往拥有较长的寿命,所以增加新生的对象的扫描,减少老生对象的扫描
(2)过程
-
GC小回收:利用复制收集,将新空间标记为老生代或利用标记清除方式将存活对象标记为老生代,清除死亡对象
-
GC大回收(偶尔进行):以全部区域为对象进行GC操作
(3)记录集
-
在对象引用发生改变时,如果老生代对象引用到了新生代对象,则将引用记录加入到记录集
-
需要时刻保持更新,新生代被老生代引用的瞬间就必须更新
(4)写屏障
需要将添加到记录集的操作嵌入到对象修改的地方,对所有涉及修改对象的地方进行保护
(5)优缺点
-
减少了需要扫描的对象,缩短GC时间
-
算法受到程序行为,分代数量,大回收的触发条件的影响
2.3.2 增量回收
(1)原理
-
将GC操作分为多个阶段进行
-
与分代回收相似,需要增加写屏障,防止存活的对象被清除,而该清除的对象没被清除
(2)优缺点
中断时间取决于对象的数量,在牺牲总GC时间的情况下,缩短中断时间
2.3.3 并行回收
(1)原理
-
程序运行和GC同时进行
-
需要写屏障对状态进行实时更新
(2)特点
-
在GC的某个阶段还是需要暂停程序的运行,无法完全与程序并行
-
未来趋势
2.4 GC大一统理论
所有的GC算法都是跟踪回收和引用计数的结合,两者相互独立,对其中一方进行改善的技术之中必然存在对另一方的改善技术,而其结果只是两种的结合
3 思维导图
总结
原文链接:http://www.cnblogs.com/cposture/p/4845189.html