V8纵览

V8纵览

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

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

基础

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

C 代码生成过程

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

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

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

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

JavaScript 生成过程

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

Single-Threaded

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

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

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

Ignition & TurboFan

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

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