JS垃圾回收机制

Chrome浏览器的垃圾回收过程:
(1)通过 GC Root (根对象)标记空间中活动对象和⾮活动对象。
⽬前 V8 采⽤的可访问性算法来判断堆中的对象是否是活动对象。这个算法是将⼀些 GC Root 作为初始存活的对象的集合,从 GC Roots 对象出发,遍历 GC Root 中所有对象:
● 通过 GC Root 遍历到的对象是可访问的,必须保证这些对象应该在内存中保留,可访问的对象称为活动对象
● 通过 GC Roots 没有遍历到的对象是不可访问的,这些不可访问的对象就可能被回收,不可访问的对象称为⾮活动对象

**(2)回收⾮活动对象所占据的内存。**其实就是在所有的标记完成
之后,统⼀清理内存中所有被标记为可回收的对象。

(3)**内存整理。**⼀般来说,频繁回收对象后,内存中就会存在⼤量不连续空间,这些不连续的内存空间称为内存碎⽚。当内存中出现了⼤量的内存碎⽚之后,如果需要分配较⼤的连续内存时,就有可能出现内存不⾜的情况,所以最后⼀步需要整理这些内存碎⽚。这步其实是可选的,因为有的垃圾回收器不会产⽣内存碎⽚。
这里提一下V8之前垃圾回收机制的策略:
**引用计数法:**引用计数法它的原理就是当一个对象被引用一次之后,引用数就加1,然后取消应用的时候就应用数会减一。当引用数为0的时候,触发垃圾回收机制开始回收。

问题:在v8之前的话,引用计数法它其实是有一个问题的,比如说你在写一个循环里边,那他其实这个对象一直被引用的,那它引用数就不可能为0,所以说就永远不能被垃圾回收机制去回收。

**标记清除法:**标记清除法的话,它主要原理的话就是先标记后清除,也是从跟对象开始把所有的对象标记为0。存活的对象标记为1,然后清掉所有标记为0的对象之后,最后把所有标记为1的对象再标记为零,方便下次回收。

**问题:**在v8之前标记清除法它其实也有一个弊端,就是每次清除完为零的对象之后,剩余的位置的话它是有不连续的,再有新对象进来的时候会触发一个就是找位置策略,找位置策略的话有一个first fit/ best fit和worst fit。first fit他其实就是找到能放下新对象的第1个位置,直接放,best fit它其实就是找到能放下新对象的一个最小块,worst fit其实就是找到一个最大的块,然后再切一块空间给新对象.

以上就是⼤致的垃圾回收流程。⽬前 V8 使用了两个垃圾回收器:主垃圾回收器和副垃圾回收器。下面就来看看 V8 是如何实现垃圾回收的。

在 V8 中,会把堆分为新生代和老生代两个区域,新生代中存放的是生存时间短的对象,老生代中存放生存时间久的对象:

在这里插入图片描述
新⽣代通常只⽀持 1~8M 的容量,⽽⽼⽣代⽀持的容量就⼤很多。对于这两块区域,V8分别使⽤两个不同的垃圾回收器,以便更⾼效地实施垃圾回收:
● 副垃圾回收器:负责新⽣代的垃圾回收。
● 主垃圾回收器:负责⽼⽣代的垃圾回收。

(1)副垃圾回收器(新生代)
新生代区域,主要存放新的/小的/存活时间短的对象,它内部分出两个内存空间,一个是使用空间,也就一个是闲置空间,当使用空间满的时候,然后标记出存活的一个对象,然后把存活的对象放到闲置区域,然后再清空使用空间,最后把闲置空间和使用空间交换位置,方便下次回收。

(2)主垃圾回收器(老生代)
老生代区域,主要存放老的的/大的/存活时间长的对象,老生代区域其实也是用了一个标记清除法,就是从根对象开始把所有的对象标为零,存活的对象标记为1,然后清掉所有为0的对象,最后把存活的对象再标为0,方便下次回收,另外的话它还通过一个标记压缩算法,把所有为零的对象按照顺序排放,在有新对象进来的时候直接按顺序添加就行,把之前位置不连续的问题给解决了。

另外还有一些优化策略:
**惰性清理:**在清理非活动对象时,如果剩余空间足够JavaScript代码运行,垃圾回收器可能会延迟清理,让JavaScript代码先执行。

**并发与并行:**V8还支持并发和并行垃圾回收,允许主线程和辅助线程同时执行垃圾回收工作,进一步提高效率。

Chrome浏览器的垃圾回收过程是一个复杂的系统,通过分代式垃圾回收机制、多种算法和优化策略,有效地管理着浏览器的内存资源,确保应用的稳定运行和高效性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值