V8 纵览

V8 纵览

V8 是用 C++ 编写的 Google 开源高性能 JavaScript 和 WebAssembly 引擎,用于 Chrome 和 Node.js 等运行环境。换句话说,V8 是用 C++ 开发的软件,可将 JavaScript 转换为可执行代码,即机器代码。

在这个顿悟时刻,我们开始更清楚地看到事物。Google Chrome 和 Node.js 都只是将 JavaScript 代码传输到其最终目的地的桥梁:在该特定机器上运行的机器代码。V8 性能表现中的另一个重要角色是其世代和超精确的垃圾收集器。它经过优化,可以使用低内存来收集 JavaScript 不再需要的对象。除此之外,V8 还依靠其他工具和功能来改善某些固有的 JavaScript 功能,这些功能在历史上使该语言变慢(例如,其动态特性)。

基础

机器代码如何工作?简而言之,机器代码是一堆非常低级的指令,它们在机器内存的特定部分中执行。使用 C++ 语言作为参考的生成过程与此类似:

C 代码生成过程

在继续进行之前,必须指出这是一个编译过程,与 JavaScript 解释过程不同。实际上,尽管编译器会在过程结束时生成整个程序,但解释器将作为程序本身工作,通过读取指令(通常是脚本,如 JavaScript 脚本)并将其转换为可执行命令来完成任务。解释过程既可以是即时的(解释器仅在其中解析并运行当前命令),也可以是完全解析的(即解释器在继续处理相应的机器指令之前首先完全翻译脚本)。

回到图中,众所周知,编译过程通常从源代码开始。您实现代码,保存并运行。反过来,正在运行的过程从编译器开始。像其他程序一样,编译器是在您的计算机上运行的程序。然后,它将遍历所有代码并生成目标文件。这些文件是机器代码。它们是在特定计算机上运行的经过优化的代码,这就是为什么从一个操作系统迁移到另一个操作系统时必须使用特定的编译器的原因。但是您无法执行单独的目标文件,需要将它们合并为一个文件,即众所周知的 .exe 文件(可执行文件)。那是链接器的工作。

最后,加载程序是负责将该 exe 文件中的代码传输到操作系统的虚拟内存的代理。它基本上是一个运输者。在这里,您的程序终于启动并运行。听起来像一个漫长的过程,不是吗?在大多数情况下(除非您是在银行大型机中使用 Assembly 的开发人员),您都将花费时间用高级语言进行编程:Java,C#,Ruby,JavaScript 等。

语言越高,速度越慢。这就是为什么 C 和 C++ 如此之快的原因,它们非常接近于机器代码语言:汇编语言。除了性能之外,V8 的主要优点之一就是可以超越 ECMAScript 标准并了解例如 C++:

JavaScript 生成过程

JavaScript 仅限于 ECMAScript。V8 为了存在,必须符合但不限于此。能够将 C++ 功能集成到 V8 中的能力很棒。由于 C++ 已发展成为非常擅长于操作系统的特殊性(例如文件操作和内存/线程处理),因此掌握所有这些功能非常有用。如果您考虑一下,Node.js 本身就是以类似的方式诞生的。它采用了类似的方式来升级到 V8,再加上服务器和网络功能。

Single-Threaded

如果您是 Node 开发人员,那么您将熟悉 V8 的单线程性质。每个 JavaScript 执行上下文都与一个线程成正比。当然,V8 在后台管理 OS 线程机制;它是一个复杂的软件,并且可以同时执行许多工作,因此可以使用多个线程。

我们有一个执行代码的主线程,另一个用于编译代码的线程(是的,每次编译新代码时我们都无法停止执行),还有一些用于处理垃圾回收,等等。但是,V8 为每个 JavaScript 的执行上下文创建了一个线程的环境,其余的保持在其控制之下。

想象一下您应该执行 JavaScript 代码的函数调用栈。JavaScript 通过按照插入/调用每个函数的顺序将一个函数堆叠在另一个函数之上来工作。在介绍每个功能的内容之前,我们无法知道它是否调用了其他功能。如果发生这种情况,那么被调用的函数将被放置在堆栈中调用者之后。例如,当涉及到回调时,它们被放置在堆栈的末尾。V8 的主要任务之一是管理该堆栈组织和该过程所需的内存。

Ignition & TurboFan

自 2017 年 5 月发布 5.9 版以来,V8 附带了一个新的 JavaScript 执行管道,该管道基于 V8 的解释器 Ignition 构建。它还包括更新更好的优化编译器 ⁠- TurboFan。这些更改完全集中在整体性能以及 Google 开发人员在使引擎适应 JavaScript 世界提出的所有快速而重大的更改时面临的困难。

从项目一开始,V8 的维护者就一直担心要找到一种以 JavaScript 不断发展的步伐来提高 V8 性能的好方法。现在,我们可以在以最高基准运行新引擎时看到巨大的改进: