图解 Google V8
李兵
前盛大创新院高级研究员
26763 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 25 讲
图解 Google V8
15
15
1.0x
00:00/00:00
登录|注册

21 | 垃圾回收(二):V8是如何优化垃圾回收器执行效率的?

部分方案应用
增量标记
并行清理
并发标记
辅助线程后台执行
写屏障机制
三色标记法
将标记工作分解为小任务
辅助线程并行处理
避免内存泄漏
副垃圾回收器
主垃圾回收器
并发回收
增量式垃圾回收
并行回收
全停顿
主线程执行
思考题
综合应用
优化方案
V8垃圾回收器
垃圾回收优化技术

该思维导图由 AI 生成,仅供参考

你好,我是李兵。
上节我们介绍了 V8 使用副垃圾回收器和主垃圾回收器来处理垃圾回收,这节课我们看看 V8 是如何优化垃圾回收器的执行效率的。
由于 JavaScript 是运行在主线程之上的,因此,一旦执行垃圾回收算法,都需要将正在执行的 JavaScript 脚本暂停下来,待垃圾回收完毕后再恢复脚本执行。我们把这种行为叫做全停顿(Stop-The-World)
一次完整的垃圾回收分为标记和清理两个阶段,垃圾数据标记之后,V8 会继续执行清理和整理操作,虽然主垃圾回收器和副垃圾回收器的处理方式稍微有些不同,但它们都是主线程上执行的,执行垃圾回收过程中,会暂停主线程上的其他任务,具体全停顿的执行效果如下图所示:
可以看到,执行垃圾回收时会占用主线程的时间,如果在执行垃圾回收的过程中,垃圾回收器占用主线程时间过久,就像上面图片展示的那样,花费了 200 毫秒,在这 200 毫秒内,主线程是不能做其他事情的。比如,页面正在执行一个 JavaScript 动画,因为垃圾回收器在工作,就会导致这个动画在这 200 毫秒内无法执行,造成页面的卡顿 (Jank),用户体验不佳。
为了解决全停顿而造成的用户体验的问题,V8 团队经过了很多年的努力,向现有的垃圾回收器添加并行、并发和增量等垃圾回收技术,并且也已经取得了一些成效。这些技术主要是从两方面来解决垃圾回收效率问题的:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

V8引擎通过优化垃圾回收器的执行效率来提升性能。JavaScript运行在主线程上,因此垃圾回收算法的执行会导致脚本暂停,称为全停顿。为了解决全停顿带来的用户体验问题,V8团队引入了并行、并发和增量等垃圾回收技术。并行回收机制通过引入多个辅助线程来并行处理垃圾回收任务,加速执行速度。副垃圾回收器采用了并行策略,启动多个线程来负责新生代中的垃圾清理操作,同时更新引用这些对象的指针。这些技术的应用消除了单个长的垃圾回收任务,减少了主线程暂停的时间,改善了页面卡顿问题,使动画、滚动和用户交互更加流畅。通过这些优化,V8引擎在垃圾回收执行效率方面取得了一定成效。另外,增量式垃圾回收和并发回收机制也被引入,进一步提高了垃圾回收的效率和性能。增量式垃圾回收将标记工作分解为更小的块,并且穿插在主线程不同的任务之间执行,而并发回收则允许辅助线程在后台完成执行垃圾回收的操作,避免了主线程被挂起。这些技术的融合使得V8引擎在垃圾回收方面取得了显著的进展,为提升JavaScript执行效率和用户体验做出了重要贡献。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《图解 Google V8》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(14)

  • 最新
  • 精选
  • sugar
    先说说思考题:内存泄漏问题的定位,一般是通过chrome的devtool中memory report来观察的,nodejs环境中的mem leak case我们研究的比较多,一般通过结合memwatch等c++扩展包把report文件dump在线上机磁盘上,然后download下来在本地的chrome浏览器devtool中进行复盘。比较常见的case是一些js工程师对scope的理解不够深,复杂的闭包里出现了隐式的引用持有却没释放。此类问题一般隐蔽性比较强,而且如果不是大厂的业务线(业务高峰产生高并发环境),往往可能压根发现不了,因为就算有leak 内存逐渐增长到v8的heap limit后node进程死掉就会被pm2/forever等守护进程复活,这个重启只要不是非常频繁往往是业务无感的~

    作者回复: 你是一线专家👍

    2020-05-02
    99
  • Shine
    这跟JVM的垃圾回收机制一模一样

    作者回复: 类似的

    2020-05-13
    6
  • HoSalt
    别把对象关联到全局变量上,避免循环引用

    作者回复: 对

    2020-05-03
    5
  • sugar
    另外还想请教一点,不知我的理解对不对。在nodejs这一端,结合今天的课程我们知道v8的gc是有线程优化的,那么是不是说 在线上服务器,我们如果给node提供2核心甚至更多核心的运行环境,能够使gc的stw时间更短?gc效率更高? 不知这一点我的理解对不对,如果对的话,引申出一个值得探讨的问题:我们作为线上node集群的资源利用管理角度,应该如何判定当前的node进程gc的stw时间是多长,我又该提供给它多少核心的宿主环境 能够让gc效率达到最优呢?
    2020-05-02
    16
  • 避免没错泄露很重要一点就是避免对象的循环引用,这个很容易造成这个对象永远不会被标记而持续占用内存,同时大对象或大数组最好在使用完之后赋值为undefined释放内存~还有一点就是使用angular等框架的时候对事件的监听要在组件销毁的同时移除监听,否则这个监听的回调函数所占用内存也是不会释放的~以上是我在做项目性能优化的时候总结的一些点,应该是比较常见但又容易被忽视的吧😁
    2020-11-22
    1
    4
  • 杨阳
    感觉并发回收和并行回收有点不明白,并行不会阻塞主线程吧,并发会阻塞主线程。
    2020-10-28
    1
    2
  • samuel
    并行回收,垃圾回收所消耗的时间,等于辅助线程数量乘以单个线程所消耗的时间加同步开销,这样的话,效率还不如直接在主线程执行垃圾回收,不明白并行回收的优势在哪
    2020-07-19
    1
    2
  • sheeeeep
    请教一下,写屏障机制有一点没理解。文中说,当黑节点指向白节点,会把白节点变为灰节点。但是,黑节点表示自己和子节点都已经标记为引用,灰节点表示子节点还没开始标记,那黑节点指向灰节点是矛盾的吗?
    2020-05-03
    3
    2
  • 余亚勇
    老师我想问一下,您在文中说: 采用并行回收时,垃圾回收所消耗的时间,等于总体辅助线程所消耗的时间(辅助线程数量乘以单个线程所消耗的时间) 为什么是辅助线程时间的总和?这样的话采用并行的意义是什么?
    2021-09-28
    1
  • BlingBling
    老师您好,有一个问题想不明白,既然并发回收的方式是在辅助线程上执行的,并不会占用主线程的CPU,那么垃圾回收器为什么不直接完全使用并发回收呢?这种方式是对主线程影响最小的。 在垃圾回收的过程中,JS主线程扮演的是一个什么角色呢?垃圾回收是否一定依赖主线程呢? 希望老师帮忙解一下疑惑
    2020-12-16
    2
    1
收起评论
显示
设置
留言
14
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部