垃圾回收算法

概念

垃圾回收器的作用是,跟踪监测已经分配的内存,发现不再被使用的内存,阶段性地进行回收。

在语言级别上引入自动垃圾回收算法,是避免内存泄漏的最佳方案。

算法

  • 引用计数

    每个对象内部维护一个整数值,用于该对象的引用计数:当对象被引用时引用计数加一,当对象不被引用时引用计数减一,当引用计数为 0 时,自动销毁对象。

    缺陷有两个:一是每次对象赋值都要引用计数加一,增加了系统消耗。二是不能解决循环引用的问题。循环引用是指对象 A 和对象 B 互相持有对方的引用,这样两个对象的引用计数都不是 0 ,因此永远不能被收集。

目前引用计数法主要用在 c++ 、 PHP、python 中。 

  • 标记清除

    该算法分为两步:标记和清除。 从程序的根节点开始递归地遍历所有对象,将能遍历到的对象打上标记,将所有未标记的对象当作垃圾销毁。

    但是这个算法缺陷也有两个,一是STW 问题(Stop The World),算法在标记时必须暂停整个程序。 二是当程序中的对象逐渐增多时,递归遍历整个对象树会消耗很多的时间,在大型程序中这个时间可能会是毫秒级别的,让所有的用户等待几百毫秒的 GC 时间这是不能容忍的。

 golang 1.5以前使用的这个算法。

  • 三色标记

   三色标记法是在标记清除法基础上的改进,它是一个并发的 GC 算法。 
其原理是,创建三个集合:白、灰、黑,将所有对象放入白色集合。 
然后从根节点开始遍历所有对象,把遍历到的对象从白色集合放入灰色集合。 
之后遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将此灰色对象放入黑色集合,最后收集所有白色对象(垃圾) 

    这个算法可以实现 “on-the-fly”,也就是在程序执行的同时进行收集,并不需要暂停整个程序。 但是也会有一个缺陷,可能程序中的垃圾产生的速度会大于垃圾收集的速度,这样会导致程序中的垃圾越来越多,不能及时地被收集掉。 

使用这种算法的是 Go 1.5、Go 1.6。

  • 分代收集

    分代收集是传统标记清除法基础上的另一个改进,按照对象的生命周期长短来进行分代,然后给内存用量设定几个阀值,到达某个阀值时触发相应分代级别的回收。 一般都会分三代,在 java 中称之为新生代、年老代和永久代

    原理:新对象放入新生代;当内存用量超过一个较小的阈值时,触发新生代的收集;新生代中幸存的对象(未被收集)放入老年代;只有当内存用量超过一个较高的阈值时,才会触发老年代的收集;永久代的收集同理。因为新生代中的对象十分少,所以新生代的收集会非常快(比年老代快几个数量级),只有内存消耗过于大的时才会触发较慢的年老代和永久代的收集。

使用的语言有 java、.NET 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值