Skip to content
目录

7. 关键设计决策

这一篇用于把前面的知识点串成“为什么 V8 要这样设计”。

为什么要分层执行

冷代码不值得重度优化,热代码才值得投入编译成本。

所以 V8 用 Ignition 保启动,用 Sparkplug 快速提速,用 Maglev / Turbofan 处理热点代码。这是在 启动速度、内存、峰值性能 之间做平衡。

为什么要分代 GC

大部分对象很快死亡。把新对象放在新生代,可以用更便宜的方式频繁回收;活得久的对象再晋升到老生代,减少重复搬迁成本。

为什么需要写屏障

GC 执行时,JS 代码可能还在修改对象引用。写屏障用来维护跨代引用和增量标记正确性。

没有写屏障,年轻代 GC 可能漏掉老年代指向新生代的对象;增量标记也可能因为引用变化而误回收对象。

为什么要指针压缩

JS 堆里引用非常多,64 位指针会带来明显内存开销。指针压缩用 32 位偏移表示堆内引用,换取更低内存占用和更好的缓存表现。

代价是地址布局和安全机制更复杂。

为什么 Context 需要 global proxy

浏览器需要隔离不同页面、iframe、扩展脚本等全局环境。global proxy 让宿主可以代理和控制全局对象,同时不破坏 V8 内部对真实 global object 的假设。

为什么微任务策略由嵌入方控制

V8 是引擎,不是完整浏览器或 Node。不同宿主对“什么时候清空微任务队列”的定义不同,所以 V8 提供策略,宿主负责接入自己的事件循环。

总结

V8 的核心设计都在做权衡:执行分层平衡启动和性能,分代 GC 平衡吞吐和停顿,写屏障保证并发 GC 正确性,指针压缩降低内存,Context 和微任务策略服务嵌入场景。

MIT License.