v8引擎采用分代垃圾回收机制提升效率:新生代用scavenge算法(cheney半空间复制)快速回收短命对象,老生代用mark-sweep+mark-compact按需处理长存对象,并通过对象晋升、增量与并发标记进一步优化性能。

V8 引擎通过分代收集机制显著提升内存回收效率,核心在于按对象生命周期差异,匹配不同回收策略,避免“一刀切”式扫描整个堆。它不靠增加算力,而是用更聪明的分区与算法分工,把有限的 GC 开销花在最值得的地方。
新生代用 Scavenge 算法快速清理短命对象
新生代空间小(通常 1–8 MB),专放刚创建的临时对象(如函数内局部变量、中间计算结果)。Scavenge 采用 Cheney 半空间复制:
- 把新生代均分为 From 和 To 两个区域,只用其中一块分配新对象
- 当 From 满时,仅遍历并复制存活对象到 To 空间,未存活的直接丢弃
- 复制完后交换 From/To 角色,原 From 空间清空重用
这种设计让单次新生代 GC 时间稳定在毫秒级——因为只处理少量存活对象,且完全规避内存碎片。90% 以上的对象在此阶段就被高效回收。
老生代用 Mark-Sweep + Mark-Compact 按需处理长存对象
老生代容纳晋升对象、全局变量、大数组等长期存活数据,空间可达 GB 级。这里不用复制算法(复制大对象太贵),改用标记类算法:
- 标记阶段用三色标记法(白→灰→黑)并发或增量执行,减少主线程停顿
- 清除阶段释放不可达内存,但可能留下碎片
- 当碎片率超过阈值(如 20%),才触发 Mark-Compact,把存活对象向一端压缩对齐
也就是说:不频繁整理,只在真正需要时才整理。大部分时间只做轻量标记+清除,兼顾吞吐与响应。
对象晋升机制让回收更精准
不是所有对象都经历相同路径:
- 新对象默认进新生代
- 经历两次 Scavenge 仍存活 → 晋升到老生代
- 大对象(如
new Array(1e6))直接分配到老生代 - To 空间使用率超 25% 时,部分对象提前晋升,防止复制失败
这确保新生代始终“轻装上阵”,老生代也只积累真正稳定的对象,大幅降低各代内无效扫描比例。
增量与并发标记进一步摊薄卡顿
V8 在标记阶段不再“全停顿”:
- 增量标记把一次大标记拆成多个微任务,穿插在 JS 执行间隙中
- 并发标记允许辅助线程在后台扫描对象图,主线程继续运行
用户感知的页面卡顿因此明显减少,尤其在复杂应用中效果显著。
不复杂但容易忽略











