吃掉V8,看V8引擎如何翻江倒海

一直好奇V8引擎的运转原理和垃圾回收,是如何提升浏览器的渲染,今天,我们就一起来一探究竟。

在了解V8引擎以前,我们先来了解一下什么是javascript引擎?

简单来说,CPU并不直接识别js代码,不同的CPU只识别自己对应的指令集,javascript引擎将js代码编译成CPU认识的指令集,当然除了编译之外还要负责执行以及内存的管理,js由引擎直接读取源码,一边编译一边执行,这样效率相对较低,而编译形语言(如c++)是把源码直接编译成可直接执行的代码执行效率更高, V8便在这样的场景下诞生了。

那,什么是V8引擎?

V8使用C++开发,并在谷歌浏览器中使用。在运行JavaScript之前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8将其编译成原生机器码(IA-32, x86-64, ARM, or MIPS CPUs),并且使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序。

了解V8后,我们一起来看一下V8的作用原理

V8将javascript代码编译成抽象语法树再转化成字节码,通过解释器来执行,并通过JIT工具将部分字节码转化成可直接执行的本地代码。V8直接将抽象语法树通过JIT技术转换成本地代码,放弃了在字节码阶段可以进行的一些性能优化,但保证了执行速度。虽然少了生成字节码这一阶段的性能优化,但极大减少了转换时间。

接下来,我们一起来看一下V8编译运行过程

首先我们了解一下在执行编译运行过程中所用到的几个类

    Script类:表示是JavaScript代码,既包含源代码,又包含编译之后生成的本地代码,所以它既是编译入口,又是运行入口;

    Compiler类:编译器类,辅助Script类来编译生成代码,它主要起一个协调者的作用,会调用解释器(Parser)来生成抽象语法树和全代码生成器,来为抽象语法树生成本地代码;

    Parser类:将源代码解释并构建成抽象语法树,使用AstNode类来创建它们,并使用Zone类来分配内存;

    AstNode类:抽象语法树节点类,是其他所有节点的基类,它包含非常多的子类,后面会针对不同的子类生成不同的本地代码;

    AstVisitor类:抽象语法树的访问者类,主要用来遍历抽象语法树;

    FullCodeGenerator:AstVisitor类的子类,通过遍历抽象语法树来为JavaScrit生成本地代码

进行编译运行过程,让我们一起看看V8是如果运转的

一、解析器parser将js代码转化为抽象语法树

二、解释器Interpreter负责将抽象语法树解释称字节码byteCode,同时解释器也有直接解释执行byteCode的能力

三、编译器负责编译解析出运行更加高效的机器代码(此处需要注意V5.9版本前没有解释器,是由两个编译器组成,参考下图,观看两个版本的编译过程

V5.9后

V5.9前

第一步,经过解析器parse解析为抽象语法树后,经过Full-codegen编译器生成浏览器可是别的机器代码,而不进行中间转换,Full-codegen编译器生成的代码是未被优化的代码。

当代码运行一段时间后,V8引擎中的分析器线程收集到了足够多的数据来帮助另一个编译器crankShaft来做代码优化,需要优化的源码需要重新生成新的ast抽象语法树,新的ast再经过crankShaft编译生成优化后的机器代码,来提升运行效率。具体过程如下图所示

老版本的编译原理主要存在以下缺点?

1、机器码占用大量内存

2、缺少中间机器码,无法实现一些优化策略

3、不能很好的支持和优化新的js语法特征

于是v8团队为解决以上问题,开发了一套新的V8架构,接下来,我们一起走进V8新世界吧~~~

一,parse阶段没有变化,在生成AST阶段后,新增了基准解释器这一流程igniton,来生成字节码,此时AST就被清除掉了,释放内存空间。生成的byteCode直接被解释器执行,同时生成的byteCode将作为基准执行模型,字节码更加简洁,生成的byteCode大小相当于等效的基准机器代码的25% ~ 50%左右。

二、在代码的不断运行的过程中,解释器interpreter收集到了很多可以用来优化代码的信息,比如变量的类型,执行函数的次数,这些信息被发送给V8新的编译器,TruboFun(优化编译器)。新的编译器会根据这些信息和字节码来编译出经过优化的新的机器代码

1.先根据需要编译和生成这些本地代码,也就是使用编译阶段那些类和操作。

2.在V8中,函数是一个基本单位,当某个JavaScript函数被调用时,V8会查找该函数是否已经生成本地代码,如果已经生成,则直接调用该函数。否则,V8引擎会生成属于该函数的本地代码。这就节约了时间,减少了处理那些使用不到的代码的时间。

3.其次,执行编译后的代码为JavaScript构建JS对象,这需要Runtime类来辅组创建对象,并需要从Heap类(运行本地代码需要使用的内存堆类)分配内存。

4.最后,借助Runtime类(运行这些本地代码的辅组类,主要提供运行时所需的辅组函数,如:属性访问、类型转换、编译、算术、位操作、比较、正则表达式等;)中的辅组函数来完成一些功能,如属性访问等。最后,将不用的空间进行标记清除和垃圾回收(MarkCompactCollector:垃圾回收机制的主要实现类,用来标记、清除和整理等基本的垃圾回收过程, SweeperThread:负责垃圾回收的线程。)

以上就是V8编译过程,感兴趣的小伙伴,欢迎提出批评意见,还是跟以前一样,我们将会留一个小问题,留待下一篇文章的时候给出解答,今天的问题是,V8引擎在处理js执行过程中,都有哪些优化策略?还是老规矩,下篇文章会给出参考答案,也欢迎小伙伴积极留言回答。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • 前言 V8引擎如何编译和优化JS的 什么是V8 官网: https://v8.dev/[https://v8.de...
    small_zeo阅读 1,766评论 0 1
  • 前言 今天看了一个视频,关于V8引擎是如何运行JS的。我将视频中主要的知识点记下来,一来加深记忆,二来方便复习 什...
    深度剖析JavaScript阅读 1,492评论 1 11
  • v8引擎出现的原因 这里先说一下什么是编译型语言和解释性语言: 编译型语言: 在程序执行之前必须进行专门的编译过程...
    iyifei阅读 1,821评论 0 3
  • v8引擎详解 JavaScript绝对是最火的编程语言之一,一直具有很大的用户群,随着在服务端的使用(NodeJs...
    小乐子不爱吃肉阅读 7,947评论 0 5
  • JavaScript绝对是最火的编程语言之一,一直具有很大的用户群,随着在服务端的使用(NodeJs),更是爆发了...
    不去解释阅读 2,394评论 1 16