当前位置: 首页 > 后端技术 > Node.js

V8引擎详解(一)——概述

时间:2023-04-03 17:10:26 Node.js

背景在现有的javascript引擎中,V8引擎绝对是其中的佼佼者。chrome和node底层都使用了V8引擎,chrome的市场占有率达到了70%,而node是前端工程化和边界拓展的核心支柱。V8引擎对于一个前端开发工程师的重要性可想而知。我们大多数javascript开发者可能没有机会自己开发javascript引擎,但是学习V8引擎绝对是我们提升技术能力的重要途径,所以特地查阅各种书籍和文章进行学习,整理了一个系列文章供大家共同学习进步。(本文为系列文章的第一篇)什么是V8引擎javascript引擎在我们了解V8引擎之前,首先要知道什么是javascript引擎。简单的说就是CPU不知道我们的js代码,不同的CPU只知道自己对应的指令集。javascript引擎将js代码编译成CPU可以识别的指令集。当然,除了编译之外,它还负责执行和内存管理。大家都知道js是一种解释型图形语言。引擎直接读取源代码,边编译边执行。这是比较低效的,而编译型图形化语言(如C++)直接将源代码编译成可以直接执行的代码。执行效率更高。(图片转载自https://zhuanlan.zhihu.com/p/...)随着技术的发展,v8引擎对JavaScript性能的要求越来越高,可以更快的解析和执行JavaScript代码,V8引擎就是在这种背景下产生的,其目的就是为了提高性能。为了提高性能,v8从很多同样解释图形语言的前辈那里吸取了很多经验。再来看看同样解释图形语言的java的运行过程。参考文章:什么是JIT:https://blog.csdn.net/qq_3604...下面我们来看看V8是怎么做的。整个过程很像java的编译执行过程,将javascript代码编译成抽象语法树,然后转换成字节码,由解释器执行,部分字节码由JIT转换成直接可执行的native代码工具。Java分两个阶段完成,编译阶段尽可能生成高效的字节码。V8更直接的通过JIT技术将抽象语法树转化为本地代码,放弃了一些可以在字节码阶段进行的性能优化,但保证了执行速度。虽然少了生成字节码阶段的性能优化,但是转换时间大大减少了。V8编译运行过程接下来了解下V8的编译过程和运行过程包含编译后生成的本地代码,所以既是编译入口又是运行入口;Compiler类:Compiler类,辅助Script类编译生成代码,它主要起到协调者的作用,会调用解释器(Parser)生成抽象语法树和全代码生成器为抽象语法树生成native代码;Parser类:将源代码解释构建成抽象语法树,使用AstNode类创建,使用Zone类分配内存;AstNode类:抽象语法树节点类,是所有其他节点的基类。它包含很多子类,后面会针对不同的子类生成不同的本地代码;AstVisitor类:抽象语法树的访问者类,主要用于遍历抽象语法树;FullCodeGenerator:AstVisitor类的子类,通过遍历抽象语法树为JavaScrit生成原生代码;原图出处:《WebKit技术内幕》(红色标记为作者自己理解,如有偏差或错误,请指出并讨论)compilation,即编译入口和执行入口;Execution:运行代码的辅助组类,包括一些重要的函数,比如Call函数,辅助Script代码的进入和执行;JSFunction:需要执行的JavaScript函数表示类;Runtime:运行这些本地代码的辅助类,主要提供运行时所需的辅助功能,如:属性访问、类型转换、编译、算术、位运算、比较、正则表达式等;Heap:运行本地代码所需要的内存堆类;MarkCompactCollector:垃圾回收机制的主要实现类,用于标记、清除、排序等基本的垃圾回收过程;SweeperThread:负责垃圾回收的线程。执行过程如下:原图来源:《WebKit技术内幕》(红色标记为作者自己理解,如有偏差或错误请指出并讨论)编译执行的整体过程如下如下:原图出处:《WebKit技术内幕》(红色标记为作者本人理解,如有偏差或错误请指出讨论)从宏观上看,但要想真正理解V8,除了这些,我们还需要理解很多操作细节,包括但不限于事件循环系统、内存管理、延迟解析、隐藏类、内联缓存等,接下来的文章会一一学习,敬请期待。了解V8引擎参考文章《WebKit技术内幕》:https://zhuanlan.zhihu.com/p/...