V8中的数据类型

1,216 阅读2分钟

基础类型

使用标记法,有效表示number值

视频

  1. ECMAScript标准是使用64位双精度来存储数字。
  2. 但是通常用的数字都是小整数。如果全部采用64位双精度来计算,会变的非常慢。
  3. V8传递了约32位数字来表示所有值,以提高效率。使用最后一位作为标记,以指示值是Smi(小整数)还是指向对象的指针。剩余的31位空间,如果是31位及以下的小整数SMI,剩余空间则存值。如果是浮点型,或者数很大,将开一块内存,创建一个HeapNumber对象来存储,剩余空间存储值该地址(32位CPU)。
| object pointer              | 1 |

or

| 31-bit-signed integer (Smi) | 0 |
  1. 在64位的CPU上,有32位空间来表示数字,1位空间作为标记。
  2. 关于HeapNumber,可以参考这一篇 看文吃瓜:React 遭遇 V8 性能崩溃的故事,里面详细讲述了小整数SMI和浮点型数转换时带来的问题和原理。
  3. 尽量使用SMI,因为SMI快。定义变量时尽量使用确定的格式,小整数SMI和浮点型数转换有一定的性能开销,浮点型数据类型确定后,不能再转为SMI了。

字符串

  1. 一般字符串在内存中的表示,高4位表示类型,其后四位存储长度,再后四位存储hash值,后面存储字符串的值。
Map |Len |Hash|Characters
0123|4567|8901|23.........
  1. 更完整的字符串所使用的类及操作请看:字符串在 V8 内的表达

Undefined Boolean

  1. 和字符串的一般形式类似。
  2. 如果你看了开始的时候,应该对所说的Map有一定的印象。Map就是对这个对象的描述,类似于AST过的结构体。

对象

  1. 看一下对象在内存中的表现形式:
+-------------------+
|  Object           |    +----> +------------------+     +---->  +------------------+
|-------------------|    |      |  FixedArray      |     |       |  FixedArray      |
|  Map              |    |      |------------------|     |       |------------------|
|-------------------|    |      |  Map             |     |       |  Map             |
  |  Extra Properties |----+      |------------------|     |       |------------------|
|-------------------|           |  Length          |     |       |  Length          |
|  Elements         |------+    |------------------|     |       |------------------|
|-------------------|      |    |  Property "poo"  |     |       |  Property "0"    |
|  Property "foo"   |      |    |------------------|     |       |------------------|
|-------------------|      |    |  Property "baz"  |     |       |  Property "1"    |
|  Property "bar"   |      |    +__________________+     |       +__________________+
+___________________+      |                             |
                           |                             |
                           |                             |
                           +-----------------------------+

这部分建议看一下李兵老师在极客时间上的图解V8专栏,里面图示比较简明。

  1. 解释FixedArray:类似于数组是一块连续的内存。
  2. 上面显示了最常见的优化表示。
  3. 所有块都有一个Map属性描述其结构,和前述所讲Map是一样的功能及描述。更多Map的解释请看 V8 之旅:对象表示
  4. V8中对象并不全是使用hashtable来表示的,因为计算hash碰撞太慢了,并且在v8编译代码时不能很好的优化。所以一般情况下对象是表现为上图所示。
  5. Elements用于存储看起来像数组索引的属性,而Extra Properties用于存储键为字符串或符号的属性。
const x = {};
x[1] = 'bar';      // ← stored in elements
x['foo'] = 'bar';  // ← stored in properties