chrome(v8)垃圾回收机制

提到垃圾回收机制就不得不提js的数据类型:

基本数据类型:有固定大小,值保存在栈内存中。

引用数据类型:大小不固定,栈内存中存储的只是堆内存的一个指针,指向堆内存中的对象空间。

由于栈内存所存的基本数据类型大小是固定的,所以其内存是操作系统自主分配和释放回收的。但是由于堆内存大小不固定,所以需要js引擎(Chrome的V8)来手动释放这些内存。

1、引用法。(引用计数法

判断一个对象的引用数,引用数为0就回收,引用数大于0就不回收,会存在两个对象相互引用从而造成内存泄漏问题。

2、分代回收。(标记清除,标记整理

新生代:存在时间短,主要由副垃圾回收器 + Scavenge算法负责。

在新生代中,还进一步进行了细分。分为nursery子代intermediate子代两个区域,一个对象第一次分配内存时会被分配到新生代中的nursery子代,如果经过下一次垃圾回收这个对象还存在新生代中,这时候我们将此对象移动到intermediate子代,在经过下一次垃圾回收,如果这个对象还在新生代中,副垃圾回收器会将该对象移动到老生代中,这个移动的过程被称为晋升。

老生代:存在时间长,主要由主垃圾回收器 + Mark-Sweep算法(标记清除) 和Mark-Compact算法(标记整理---整理清除后留下的零散空间)

Mark-Sweep(标记清理)

Mark-Sweep分为两个阶段,标记和清理阶段,之前的Scavenge算法也有标记和清理,但是Mark-Sweep算法Scavenge算法的区别是,后者需要复制后再清理,前者不需要,Mark-Sweep直接标记活动对象和非活动对象之后,就直接执行清理了。

  • 标记阶段:对老生代对象进行第一次扫描,对活动对象进行标记
  • 清理阶段:对老生代对象进行第二次扫描,清除未标记的对象,即非活动对象

3、全停顿

由于js单线程的特性,js代码执行和垃圾回收同时进行时,垃圾回收会优先于代码执行,等垃圾回收完毕,在执行js代码。这个过程成为全停顿。所以可能会导致页面卡顿, Orinoco优化提出了增量标记、懒性清理、并发、并行的方法来解决这个问题。

增量标记(Incremental marking):

咱们前面不断强调了先标记,后清除,而增量标记就是在标记这个阶段进行了优化。我举个生动的例子:路上有很多垃圾,害得路人都走不了路,需要清洁工打扫干净才能走。前几天路上的垃圾都比较少,所以路人们都等到清洁工全部清理干净才通过,但是后几天垃圾越来越多,清洁工清理的太久了,路人就等不及了,跟清洁工说:“你打扫一段,我就走一段,这样效率高”。

大家把上面例子里,清洁工清理垃圾的过程——标记过程,路人——JS代码,一一对应就懂了。当垃圾少量时不会做增量标记优化,但是当垃圾达到一定数量时,增量标记就会开启标记一点,JS代码运行一段,从而提高效率

惰性清理(Lazy sweeping)

上面说了,增量标记只是针对标记阶段,而惰性清理就是针对清除阶段了。在增量标记之后,要进行清理非活动对象的时候,垃圾回收器发现了其实就算是不清理,剩余的空间也足以让JS代码跑起来,所以就延迟了清理,让JS代码先执行,或者只清理部分垃圾,而不清理全部。这个优化就叫做惰性清理

整理标记和惰性清理的出现,大大改善了全停顿现象。但是问题也来了:增量标记是标记一点,JS运行一段,那如果你前脚刚标记一个对象为活动对象,后脚JS代码就把此对象设置为非活动对象,或者反过来,前脚没有标记一个对象为活动对象,后脚JS代码就把此对象设置为活动对象。总结起来就是:标记和代码执行的穿插,有可能造成对象引用改变,标记错误现象。这就需要使用写屏障技术来记录这些引用关系的变化。

并发(Concurrent)

并发式GC允许在在垃圾回收的同时不需要将主线程挂起,两者可以同时进行,只有在个别时候需要短暂停下来让垃圾回收器做一些特殊的操作。但是这种方式也要面对增量回收的问题,就是在垃圾回收过程中,由于JavaScript代码在执行,堆中的对象的引用关系随时可能会变化,所以也要进行写屏障操作。

并行

并行式GC允许主线程和辅助线程同时执行同样的GC工作,这样可以让辅助线程来分担主线程的GC工作,使得垃圾回收所耗费的时间等于总时间除以参与的线程数量(加上一些同步开销)。

参考文章:https://juejin.cn/post/6995706341041897486

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值