Orinoco:年轻代垃圾回收
在V8中,JavaScript对象被分配到由V8垃圾回收器管理的堆上。在之前的博客文章中,我们已经讨论了如何减少垃圾回收暂停时间(不止一次)以及内存消耗。在这篇博客文章中,我们介绍了并行Scavenger,这是V8的主要并发和并行垃圾回收器Orinoco的最新功能之一,并讨论了设计决策以及我们实施的一些备选方法。
在V8中,JavaScript对象被分配到由V8垃圾回收器管理的堆上。在之前的博客文章中,我们已经讨论了如何减少垃圾回收暂停时间(不止一次)以及内存消耗。在这篇博客文章中,我们介绍了并行Scavenger,这是V8的主要并发和并行垃圾回收器Orinoco的最新功能之一,并讨论了设计决策以及我们实施的一些备选方法。
JavaScript 性能对 V8 团队来说一直很重要,在这篇文章中,我们希望讨论一个新的 JavaScript Web Tooling Benchmark。我们最近正在使用它来识别和修复 V8 中的一些性能瓶颈。您可能已经知道 V8 对 Node.js 的强烈承诺,而这个基准测试进一步延续了这一承诺,特别是通过运行基于 Node.js 构建的常见开发者工具的性能测试。Web Tooling Benchmark 中包含的工具是现代开发者和设计师今天使用的构建现代网站和基于云的应用程序的工具。为了继续我们专注于 现实场景性能 而不是人工基准测试的努力,我们使用开发者每天运行的实际代码创建了这个基准测试。
代理自 ES2015 起便成为 JavaScript 的重要组成部分。它们允许拦截对象的基本操作并自定义其行为。代理是 jsdom 和 Comlink RPC 库 等项目的核心部分。最近,我们在提升 V8 中代理的性能方面投入了不少精力。本文将介绍 V8 的总体性能改进模式,并特别说明针对代理的改进。
大约三个月前,我作为实习生加入了V8团队(Google Munich),从那时起,我一直在研究虚拟机的 去优化器 —— 这是对我来说全新的领域,但也证明了是一个有趣且具挑战性的项目。实习的第一部分重点在于提高虚拟机的安全性。第二部分则集中于性能改进,即删除用于取消链接以前被优化的函数的数据结构,而这个结构在垃圾回收时是性能瓶颈。本博客文章描述了我实习的第二部分。我将解释V8过去如何取消链接被优化的函数,我们如何对其进行更改,以及获得了哪些性能提升。
在 JavaScript 中,一个分配的对象如果从当前函数外部可以访问,就被称为 逃逸。通常情况下,V8 会在 JavaScript 堆中分配新对象,但通过 逃逸分析,优化编译器可以确定一个对象是否可以特殊处理,因为其生命周期被证明仅限于函数的激活状态。当对新分配对象的引用不会逃逸创建它的函数时,JavaScript 引擎不需要显式地在堆中分配该对象。相反,它们可以有效地将对象的值视为函数的局部变量。这反过来又启用了各种优化,如将这些值存储在堆栈或寄存器中,或者在某些情况下完全优化掉这些值。逃逸的对象(更准确地说,不能证明其不会逃逸的对象)必须在堆中分配。
注意: 如果你更喜欢观看演示而不是阅读文章,那么请欣赏下面的视频!
JavaScript对象可以拥有与之相关的任意属性。对象属性的名称可以包含任何字符。JavaScript引擎可以选择优化的一种有趣场景是属性名称纯粹为数字的情况,尤其是数组索引。
在这篇博客中,我们想解释一下V8如何在内部处理JavaScript属性。从JavaScript的角度来看,属性的区分需求只有少数几种。JavaScript对象大多像字典一样工作,具有字符串键和任意对象值。然而,规范在迭代期间将整数索引属性和其他属性区别对待。除此之外,不论属性是否是整数索引,它们的行为大致相同。