V8垃圾回收机制

在堆中分为新生代—new_space老生代—old_space以及其余分区

新生代内存用于存放一些生命周期比较短的对象数据--初生牛犊,新生代又分为Semi space FromSemi space To两部分

老生代内存用于存放一些生命周期比较长的对象数据--老油条,老生代又分为Old pointer spaceOld data space两部分

内存大小

  • 新老生代的内存大小与操作系统有关

  • 64位新生代空间为64MB,老生代空间为1400MB

  • 32位新生代空间为32MB,老生代空间为700MB

  • 最新版node(v14)的内存为2GB

新生代的垃圾回收

回收策略

新生代采用Scavenger算法来管理内存,通过牺牲空间换取时间,代码中生成的变量会放到新生代的form区域中,当该区域放不下时,垃圾回收算法开始执行,通过广度优先遍历form区域和可达性分析,将所有的活跃对象拷贝到to区域,然后清空form区域,再然后将form区域与to区域进行身份对调

新生代晋升老生代

  • 当一个活跃对象经历过拷贝,并且to区域的使用超过25%时,该新生代即可晋升为老生代

老生代垃圾回收

老生代的对象如何产生

  • 新生代中活得久的晋升为老生代

  • 新生代中放不下的直接分配到老生代

回收策略

  • 老生代内存空间较大,不宜使用Scavenger算法,不仅空间浪费严重,拷贝所需时间也长

  • V8在老生代中采用Mark-Sweep(标记清理)和Mark-Compact(标记整理)相结合

Mark-Sweep

  • 分为标记和清除两个阶段

  • 标记阶段时,通过深度优先遍历堆中所有对象,标记出所有活跃对象,然后进入清除阶段,清除所有无标记对象

  • 这种方法会出现内存碎片化的问题

 

Mark-Compact

  • 标记整理解决了标记清除的内存碎片化问题

  • 步骤与标记清除类似,但是多出了整理的阶段,通过整理直接覆盖垃圾区域,可以较少清除的操作

     

优化

在执行垃圾回收算法时,会暂停js脚本,这种现象称为全停顿—Stop the world,如果回收时间过长,会有卡顿现象,用户体验极差

Parallel(并行执行)

  • 新生代的垃圾回收采取并行提升垃圾回收速度,他会开启多个辅助线程来执行新生代的垃圾回收工作

  • 并行执行所需时间为总时间除以参与线程的数量加上管理时间

  • 辅助线程工作期间依旧为全停顿

增量标记

  • 老生代对象又大又多,垃圾回收时间长,所以采用增量标记方式优化

  • 增量标记就是把标记工作分成多个阶段,每个阶段都只标记一部分对象,和主线线程的执行穿插进行

  • 为支持增量标记,V8采用黑白灰三色标记法以支持垃圾回收的暂停和恢复

    • 黑色表示这个节点被GC根引用到了,而且该节点的子节点都已经标记完成了

    • 灰色表示这个节点被GC根引用到了,但子节点还没被垃圾回收器标记处理,也表明目前正在处理这个节点

    • 白色表示此节点还没被垃圾回收器发现,如果本轮遍历完后仍为白色,就会被回收

  • 引入灰色标记后,就可以通过判断有没有灰色节点来判断标记是否完成了,如果有灰色节点,下次恢复的应该从灰色节点执行

Write-barrier(写屏障)

  • 当黑色指向白色节点的时候,就会触发写屏障,这个屏障会把白色节点设置为灰色

    当 a 变黑 a.b = { name: 'b1' } 变灰时,a.b 指向了 { name: 'b2'},此时 { name: 'b2'} 将强行设置为灰色

    global.a = { name: 'a' }
    global.a.b = { name: 'b1' }
    global.a.b = { name: 'b2' }

Lazy Sweeping(惰性清理)

  • 当增量标记完成后,如果内存够用,先不清理,等JS代码执行完慢慢清理

concurrent(并发回收)

  • 其实增量标记和惰性清理并没有减少暂停的总时间

  • 并发回收就是主线程在执行过程中,辅助线程可以在后台完成垃圾回收工作

  • 标记操作全部由辅助线程完成,清理工作由主线程和辅助线程配合完成(主线程参与是为了解决冲突)

并发和并行

  • 并发和并行都是同时执行任务

  • 并行的同时是同一时刻可以多个进程在运行

  • 并发的同时是经过上下文快速切换,使得看上去多个进程同时都在运行的现象

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值