8. 常见问题
V8 由哪些核心模块组成?
可以按执行链路回答:Parser 解析源码,Ignition 生成并执行字节码,Sparkplug / Maglev / Turbofan 负责不同层级的 JIT 优化,GC 负责内存回收。
JIT 是什么?
JIT 是 Just In Time,即运行时即时编译。V8 先解释执行并收集反馈,再把热点代码编译成机器码,从而兼顾启动速度和执行性能。
Isolate 和 Context 有什么区别?
Isolate 是独立 JS 运行时实例,包含堆、GC、编译状态等;Context 是同一 Isolate 里的全局执行环境。多 Context 更轻,多 Isolate 隔离更强但成本更高。
V8 的执行分层是什么?
Ignition → Sparkplug → Maglev → Turbofan。代码越热,越可能进入更高优化层;如果优化假设失败,会 deopt 回退。
OSR 是什么?
OSR 是 On-Stack Replacement。它能在热循环还没结束时,把正在执行的栈帧切换到优化代码,避免优化必须等函数返回后才生效。
Deopt 是什么?
Deopt 是优化代码的回退机制。优化器会根据类型反馈做推测,如果实际运行打破假设,就回退到解释器或 baseline,保证语义正确。
V8 GC 怎么分代?
新生代存放新创建对象,适合频繁、低成本回收;老生代存放存活较久对象,通常使用标记和整理。V8 还会通过增量、并发手段降低 STW 停顿。
写屏障解决什么问题?
写屏障在对象引用写入时记录必要信息,主要用于跨代引用和增量标记。没有写屏障,年轻代 GC 可能漏掉老年代指向新生代的对象。
remembered set 是什么?
它记录老年代里可能指向新生代的槽位。这样年轻代 GC 不必扫描整个老年代,只检查这些记录。
微任务什么时候执行?
浏览器中通常是当前 JS 调用栈清空后执行微任务,再进入后续渲染机会。Promise.then 是微任务,requestAnimationFrame 是渲染帧相关回调,二者不是一回事。
同步脚本、defer、async 有什么区别?
同步脚本会阻塞 HTML 解析;defer 并行下载,解析完成后按顺序执行;async 并行下载,下载完成后尽快执行,顺序不保证。模块脚本默认接近 defer。
V8 负责浏览器渲染吗?
不负责。V8 负责执行 JS,DOM、CSS、Layout、Paint、Composite 等由 Blink / Chromium 渲染管线负责。
指针压缩有什么用?
把堆内引用压成 32 位偏移,减少内存占用和缓存压力。代价是地址空间布局和安全策略更复杂。
V8 和 SpiderMonkey、JSC 有什么共同点?
现代 JS 引擎都趋向于:字节码或 IR、多层 JIT、IC / Shape / 隐藏类、反馈驱动优化、优化失败回退。差异主要在分层名称、GC 实现、安全机制和宿主生态。