Chrome V8 引擎性能优秀的原因
1. JIT 编译(JIT Compile)
不用字节码(bytecode)生成机器语言。V8 的 JIT 编译器在产生机器语言时,不会产生中间码。V8 不是将原始程序转换成中间语言,而是将抽象语法树直接生成机器语言并加以执行。
补充:V8 实际包含两个编译器:
- Ignition:解释器,负责把 JS 源码编译成字节码并解释执行,启动快、内存占用低。
- TurboFan:优化编译器,会在运行时收集类型/执行反馈(inline cache 等),把热点字节码编译成高度优化的机器码。冷代码回退到 Ignition,避免过度优化浪费内存。
2. 垃圾回收管理(GC)
V8 将垃圾回收管理(Garbage Collection, GC)实现为"精确的 GC"。相反,大部分 JavaScript 引擎、Ruby 及其他语言编译器使用的是保守的 GC(Conservative GC),因为保守 GC 实现简单许多。虽然精确 GC 更为复杂,但有性能上的优点。
补充:V8 使用分代式 GC,将堆分为新生代(Scavenge + Semi-Space,适合短命对象)和老生代(Major GC:Mark-Sweep + Mark-Compact,适合长命对象)。主线程尽量只做轻量工作;标记阶段可由并发/并行 GC 协助,减少 STW(Stop-The-World)卡顿。
3. 内联缓存(Inline Cache)
内联缓存可以避免方法调用和属性访问时的哈希表查找,立即缓存之前的查找结果,因此称为"内嵌"。
V8 在执行时分析程序操作,并利用"隐藏类"(Hidden Classes)为对象指定临时的类型。有了隐藏类,即使是 JavaScript 也能用上内联缓存。
4. 隐藏类(Hidden Classes)
在 V8 中建立隐藏类有两个主要原因:
- 将属性名相同的对象归类;
- 识别属性名不同的对象。
在 V8 中,符合归类条件的类会被配置在各种 JS 对象上,对象引用所配置的类。这些类只存在于 V8 内部作为优化使用,所以是"隐藏"的。
补充:日常写代码时,避免随意增删对象属性、保持对象形状稳定(先声明属性再使用、构造函数里一次性赋完),能让隐藏类保持稳定、内联缓存命中率更高,从而使 V8 产生更优的机器码。
来源整理自:vue3js.cn 面试官系列



