JS 垃圾回收机制

一.为什么会有垃圾?

        一般指无法被访问的内存(如下),如果不清理这些数据,容易造成内存泄漏

1.没有被任何内容引用的对象

var person = {name: "a1"};
person = {name: "b2"};

2.全局变量

        全局变量只有浏览器关闭或者刷新的时候才会被销毁,导致程序很难对全局变量是否为垃圾对象进行判断

3.闭包

        js垃圾回收机制理论上不回收这类型的数据。因为闭包有一个特性是存在于闭包中的变量不会被回收。而实际上不同的浏览器实现的效果可能也不一样。一些浏览器如果发现某些变量没有且不会再被使用的话,也会将其回收。

4.部分基本数据类型

        一个局部变量一旦脱离了创建它自身所在的环境(包括该环境内的子环境中),就会被视为垃圾,进行回收。比如我们在函数中定义的局部变量,当函数执行完毕后,这些变量就会被释放。由于在栈中,函数结束后本身就会释放堆栈内存,所以这种垃圾并不在我们经常讨论的范围内,一般垃圾回收的对象都是堆中的对象。

二.垃圾回收机制的策略

策略1:引用计数法

        简述:当一个对象被引用一次后,引用数就+1,当被取消引用一次,引用数就 -1 =》当引用数为0时,就会触发垃圾回收机制进行回收

        优点:立即发现垃圾   ; 对象的回收不需要另外的GC线程专门去做

        缺点:当在循环引用(对象a引用对象b,而对象b又引用对象a)的情况下,引用次数就永远不能为0,导致无法数据回收,内存就无法释放了。

策略2:标记清除法

        简述过程

                1.将所有对象标记为 0

                2.从根对象开始遍历将存活的对象标记为1

                3.然后将标记为 0 的对象进行清除

                4.最后将所有标记的对象标记为 0,方便下一次垃圾回收机制的回收

        缺点:

                清除完数据后,剩余的可用的数据不连续的,如果新加入新的对象很难找到位置。而且当回收的对象过多且位置分散,会导致性能过低。

        如何为新对象找位置?

                方法1 First-fit 👉 找到能放置下新对象的第一个块位置 (性能最好,主要采用这种)

                方法2 Best-fit 👉 找到能放置下新对象的最小的块

                方法3 Worst-fit 👉 找到最大的块,切一块空间给新对象 (容易产生更多不连续的空间)

三.V8对垃圾回收机制的优化

        1.优化标记算法(在堆内存中分出两块区域来)

                a.新生代区域

                        ① 一般存放新的,存活时间短的对象

                        ② 新生代区域的垃圾回收机制

                                分出两个空间 to空间(闲置空间) 和 from空间(使用空间)

                                当from空间中的对象要满的时候,就开始标记,将标记好的对象复制到 to空间最后再把from空间清空,然后再交换他们的名称

                b.老生代区域

                        ① 一般存放大的,老的,存活时间长的对象

                        ② 老生代的垃圾回收机制(标记清除算法 和 标记压缩算法)

                                首先将所有对象标记为 0 ,将存活对象标记为 1,将标记为 1 对象全部清空,然后将标记为 1 的对象全部标记为 0 ,最后再用标记压缩算法是他们位置整理好

        2.全停顿的优化

                起因:

                因为JS是单线程语言,所以在执行垃圾回收机制时,js执行会被暂停(一般称为全停顿)     

                优化:

                垃圾回收机制支持多线程并行回收,可以使垃圾回收机制的时间加快,最大化保证js的执行。但是这样依然会堵塞js的执行   

                再优化 ----- 增量标记 

                  增量标记,垃圾回收可以分段执行,执行一段js,就执行一次垃圾回收,使它们交叉执行,最大化保证js执行,但是如何记录上一次标记的位置

                记录上一次位置 ---- 三色标记法

                  三色标记法将上一次标记到的位置标记为灰色,当下次执行的时候从灰色开始标记

                并发回收

                   V8 中,js在主线程执行,垃圾回收可以在辅助线程执行。

                 

        

       

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值