浅谈JS垃圾回收机制

          在聊垃圾回收机制之前,我们需要先知道一个基础概念,在js中什么是垃圾,下面是我的理解:

        如果一个变量、函数、对象在js内存中不再使用了,那么就会被标记成垃圾

        比如:

                1.已经调用完毕的函数,及函数内的变量(闭包除外)等等

                2.值为null的

                3.无法被访问到的值,也就是从根(全局global)上出发,没有节点引用到的地方

        为什么要垃圾回收呢?

        因为如果js不垃圾回收,这些变量都是占用js内存的,越来越多的话,程序就会卡死。

        垃圾回收有两种方式:

        1.引用计数法:

         实现方式就是一个变量或对象等如果存在其他地方引用它,那么就给他计数,有几个引用就加几,如果后面不引用了,那么计数就减一,直到计数为0的时候,那么就会被GC(垃圾回收机制(Garbage Collection))回收

        这种方法有个缺点循环引用:

const obj1 = {name:'hh'}
const obj2 = {name:'dd'}
obj1.a = obj2
obj2.a = obj1

        两个对象内的属性相互引用,这样gc就永远清除不了了

        2.标记清除法

        什么是根?
        根就是js固有的一些变量或函数,对象等,比如全局变量,window下的一些函数,对象,这些是不会被垃圾回收的

        标记清除的实现方式就是从根出发, 根据它的引用判断哪些对象节点引用了它,然后那些对象节点又引用了哪些对象,这些都会被标记,最后那些没有标记的就被定义成了垃圾,需要被回收 比如下面红色圈圈内的就是要被删除的,因为它没有被global引用或者global下的对象引用,即使它们三个互相引用也不行
        

        这种方式有几个问题:

                1.需要占用大量的js时间去遍历,如果对象太多的话就可能会导致卡顿。

                2.有可能在你遍历过程中这个对象被修改了。

        针对上面问题有几点优化建议:

                1.分代回收

                        分代回收就是将对象等分为旧代和新代,旧代就是从新代晋升的‘长寿’对象,新代就是新创建的对象,因为新代存在时间比较短,所以我们需要间隔比较短的时间去检查一下,旧代就可以间隔长一点时间去检查。

                2、增量收集

                        可以将原本的10000个对象分成10份或者更多,分成几部分去标记回收,这样只会带来微小的延迟,效果也会比一次标记10000个对象好。

                3.闲时收集

                        利用cpu空闲时间去收集,减少对代码运行的影响

        以上是我对垃圾回收机制的一点点理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值