引用计数算法实现原理 和 优缺点

引用计数算法

  • 核心思想:设置引用数,判断当前引用数是否为 0 
  • 引用计数器
  • 引用关系改变时修改引用数字
  • 应用数字为 0 时立即回收
// reference count

const user1 = {age: 11}
const user2 = {age: 22}
const user3 = {age: 33}

const nameList = [user1.age, user2.age, user3.age]

function fn() {
    num1 = 1
    num2 = 2
}

fn()

从全局的角度出发,根上可以找到 user1、user2、user3、nameList、num1、num2它们的引用计数肯定不是 0

function fn() {
    const num1 = 1
    const num2 = 2
}

如果把 fn 中 num1 和 num2 加上声明关键字,以为着 num1 和 num2 只能在fn 的作用域内起效果,一旦 fn() 调用结束之后,从外部全局的角度出发就找不到 num1 和 num2 了,它们身上的引用计数就会归 0 ,GC就会把它们当作垃圾立即回收。也就是 说 fn() 执行结束后,fn 的内部空间就会被释放掉。而user1\user2\user3都还被引用着,此时引用计数不是 0 就不会当作垃圾被回收。

引用计数算法的优点

  • 发现垃圾时立即回收:根据当前的引用数是否为 0 来决定这个对象是不是垃圾,如果找到了可以立即释放
  • 最大限度减少程序暂停:应用程序在执行的过程中,必然会对内存进行消耗,而当前的执行平台内存肯定是有上限的,内存有占满的时候,不过由于引用计数算法是时刻监控着引用对象,当内存要占满的时候,引用计数立马找到数字为 0 的对象,对其进行释放,所以保证了内存不会有占满的时候。

引用计数算法的缺点

  • 无法回收循环引用的对象:

fn函数调用结束后,在全局下找不到 obj1 和 obj2 但是 fn 作用域范围内,obj1 和 obj2 有一个互相的指引关系,在这种情况下,它们身上的引用计数器中的数值并不是为 0 的,引用计数下的GC就没有办法将它们回收了,从而造成了内存空间的浪费

function fn() {
    const obj1 = {}
    const obj2 = {}

    obj1.name = obj2 // 对象循环
    obj2.name = obj1 // 引用数值并不为 0 ,不会释放空间,造成空间浪费

    return "deyang is a coder" 
}

fn()
  • 时间开销大:当前的引用计数需要去维护数值的变化,这种情况下要时刻的监控当前对象的引用数值是否需要修改,本身来说对象数值的修改就要消耗时间,如果有更多的对象需要修改,那么时间就会显得更大一些。所以引用计数算法相对于其它GC算法来说,时间开销会更大一些
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值