什么是 Google V8

前言

由 C/C++ 入门的我突然转 JS (主要是 Node.js) 感觉整个人都是懵逼的(还不是懂得太少造的o-O),差别真的感觉好大,最神奇的是 JS 竟然不用经过编译就可以运行。
期间总是能遇到 Google V8,不明觉厉,感觉有必要好好了解下,顺便好好梳理下基础知识。

静态编译与动态解释

众所周知,计算机只能理解机器语言,而我们平时编程用的通常是高级语言,所以源代码通常都要经过层层转换最终变成机器语言运行。

汇编器与编译器概念图

早期只有汇编语言没有高级语言,不同的设备有一套自己的对应不同机器语言指令集的汇编语言,也就是说,汇编语言不能在不同系统平台之间移植。同一个软件为了让不同类型的设备都能用要写好几套代码,实在太不方便了,所以后来发展出了跨平台的高级语言。

高级语言未出现时
高级语言出现后

随着计算机发展,编译器也越来越复杂,发展了很多分支,像是本地编译器、交叉编译器等,这里就不多说了。

那么源码一定要经过编译才能运行吗?

解释器的出现给出了一种不用编译就能运行的能力,也就是我一开始说的让我很不习惯的地方。

解释器

前面说的都算是先静态编译到可执行的文件,然后运行可执行的文件来执行程序,而解释器提供了一种边编译边运行的动态运行方法,而也正因为通过解释器运行的代码是边编译边运行的,所以运行的速度比静态编译的那种慢很多。

所以程序运行的方式分为静态编译动态解释

我从 C/C++ 跨到 JS 里,就是从静态编译跨到了动态解释里。

即时编译与虚拟机

这小节的概念了解 Java 的人应该很了解,虽然我之前接触过一点 Java 但是直到现在才算是摸清了点真面目,当然学习的过程我也没对 Java 做过多深入,毕竟主旨是 Google V8 呀!

即时编译(Just-in-time compilation)混合了编译器和解释器,在边编译边运行的过程中会将编译过的代码缓存起来,下次运行的时候运行的就是编译后的代码。

即时编译示意图

当然,虽然即时编译在运行过一次以后有了编译后的代码,再次运行时因为识别编译过的和未编译过的(即修改)代码,速度还是比静态编译的程序运行的慢。

避免二次编译也使得理论上即时编译的总体开销(编译和运行)优于静态编译和动态解释。

这里还出现了一个字节码的概念。

字节码的出现理由有点像交叉编译器(在 A 系统平台下可以产生 B 系统平台的可执行文件的编译器),在源码不能或很难编译成目标平台可执行文件时非常好用。感觉也有点像是跨平台的汇编语言,复杂度介于高级语言和低级语言之间。

在即时编译里出现的字节码是一种动态字节码转译方式,字节码也可以静态转译的,就是先编译成字节码再运行的。

字节码通常运行在一个程序虚拟机上。

字节码与虚拟机

图里的虚拟机部分也算是一个解释执行的过程。

广义的虚拟机包括一切跟任何真实机器无关的虚拟架构。
而当前虚拟机的实现主要分成三类:

  • 系统虚拟机:虚拟了一个运行完整系统的操作平台。典型代表:VirtualBox。

  • 程序虚拟机:为单个计算机程序的运行虚拟必要的环境。典型代表:Java 虚拟机。

  • 操作系统层虚拟化:介于系统和单个程序之间,可以运行多个独立应用程序,但是又不用虚拟完整操作系统。典型代表:Docker。

Google V8

终于来到了 Google V8!

V8 是 Google 开发的开源的 JavaScript 引擎,用于 Google Chrome 及 Chromium 中。

JavaScript 引擎是一个专门处理 JavaScript 脚本的虚拟机,一般会附带在网页浏览器之中。

V8 是用 C++ 写的,使用了即时编译技术,工作模式如下图:


V8 工作模式图-来自[1]

感觉到这里已经足够说明什么是 Google V8 了,后面算是拓展阅读吧。

V8 的隐藏类(Hidden Class)

JavaScript 作为一种动态编程语言,对象上的属性(Property)可以随时增减。如果用字典类的数据结构来存储这些对象属性,访问的时候就会带来动态查找的损耗,这也是 JavaScript 比类似 Java 这种类型确定的语言慢的原因之一。

V8 用动态创建隐藏类的方式来减少这种损耗。

举个例子。

有如下简单的一段 JS 代码:

function Point(x, y) {
  this.x = x; // E1
  this.y = y; // E2
}

new Point(1, 2); //  E0

语句按 E0、E1、E2 的顺序执行。

执行 E0 的时候,创建一个隐藏类 C0,对象的类指示器指向 C0。

E0 阶段

执行 E1 的时候,在 C0 基础上新建一个隐藏类 C1(C1 知道 x 属性存的位置),并给 C0 增加一个转换指示:如果增加一个 x 属性,就变成 C1。

E1 阶段

执行 E2 的时候,在 C1 基础上新建一个隐藏类 C2(C2 知道 x 和 y 属性存位置),并给 C1 增加一个转换指示:如果增加一个 y 属性,就变成 C2。

E2 阶段

隐藏类的创建过程就是隐藏类树的创建过程,在之后遇到新建对象实例,就会先试图从已创建的树里找到对应的类,没找到的话才会新建对应的树节点。

这之后,每个对象的类指示器都指向对应的隐藏类,和 Java 里的类与对象关系差不多,JavaScript 在访问属性的时候就避免了相对漫长的查找,从而加快了速度。

从这里也可以得出一个优化代码的方式:尽量用相同的顺序实例化对象属性以最大化复用隐藏类树。

GC(垃圾回收)

V8 将内存分成:

  • new-space:对象刚创建的时候分配这里的内存给对象。内存小,GC 删除的一般是这里的数据。
  • old-data-space:new-space 里的一些对象经过一轮 GC 没被删除,并且这些对象内部不包含指针(纯数据),就会被移到这里。
  • old-pointer-space:new-space 里的一些对象经过一轮 GC 没被删除,并且这些对象内部包含指针(指向别的对象),就会被移到这里。
  • large-object-space:大小超过别的 space 大小限制的对象会被放在这里,它们有专门非配的内存,不归 GC 管。
  • code-space:代码对象(包含即时编译后的指令)存放的地方。会被执行的代码不是放在这里就是放在 large-object-space 里。
  • cell-space,property-cell-space,map-space:分别存放对应名字(cells、propertyCells、maps)的地方(这里我也不太懂这啥)。

GC 首先做的是分清数据对象和指针,因为跟踪指针才能知道哪些对象是不能被回收的。

V8 的 GC 有以下几个特点:

  • 运行 GC 的时候停止执行程序。
  • 绝大多数的 GC 只处理部分数据对象内存垃圾以最小化对应用程序的影响。
  • 总是正确地知道所有的对象和指针的存储位置。这避免了将对象误认为指针导致的内存泄漏。

GC 我也没多看,也说不出个所以然来了,更多可以看A tour of V8: Garbage Collection

参考
图[1]来源
维基百科上的各种词条
Design Elements
A tour of V8: Garbage Collection

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

推荐阅读更多精彩内容