V8 垃圾回收机制

8 阅读3分钟

V8 垃圾回收机制

1. 分代垃圾回收

V8 将内存分为新生代老生代,根据对象的存活时间采用不同的回收策略。

  • 新生代:存放生命周期短的对象,内存较小(64 位系统为 32MB,32 位系统为 16MB),采用 Scavenge 算法
  • 老生代:存放生命周期长或常驻内存的对象,内存较大(64 位系统为 1.4GB,32 位系统为 0.7GB),采用 Mark-SweepMark-Compact 算法。

2. 新生代垃圾回收:Scavenge 算法

  • Cheney 算法:将新生代内存分为 From 空间To 空间,新对象分配到 From 空间。当 From 空间满时,GC 会将存活对象复制到 To 空间,非存活对象被释放,随后 From 和 To 空间角色互换。
  • 晋升条件
    1. 对象经历过一次 Scavenge 回收后仍存活。
    2. To 空间占用超过 25%(避免影响后续内存分配)。

3. 老生代垃圾回收

  • Mark-Sweep(标记清除)
    • 标记阶段:遍历堆中所有对象,标记存活对象。
    • 清除阶段:清除未标记的对象。缺点是会产生内存碎片。
  • Mark-Compact(标记整理)
    • 在 Mark-Sweep 基础上,将存活对象向一端移动,清理边界外的内存,解决内存碎片问题。
  • 触发条件
    • 空间不足时启动 Mark-Sweep。
    • 内存碎片过多时启动 Mark-Compact。

4. 优化策略

  • 增量标记(Incremental Marking)
    • 将标记过程分解为多个小任务,与 JavaScript 应用逻辑交替执行,减少主线程停顿时间。
  • 惰性清理(Lazy Sweeping)
    • 延迟清理非活动对象,优先执行 JavaScript 逻辑,按需清理内存。
  • 并发标记与清理
    • 在后台线程执行标记和清理操作,主线程继续运行 JavaScript 代码,进一步减少停顿时间。
  • 三色标记法与写屏障
    • 使用白、灰、黑三色标记对象状态,写屏障机制确保黑色对象引用白色对象时,白色对象被标记为灰色,避免漏标。

5. 内存限制与触发条件

  • 内存限制
    • 64 位系统:新生代 32MB,老生代 1.4GB。
    • 32 位系统:新生代 16MB,老生代 0.7GB。
  • 触发条件
    • 新生代:From 空间满时触发 Scavenge。
    • 老生代:空间不足或内存碎片过多时触发 Mark-Sweep 或 Mark-Compact。

6. 性能问题与改进

  • 全停顿(Stop-The-World)
    • 垃圾回收期间暂停 JavaScript 执行,影响应用性能。
  • 改进措施
    • 增量标记、惰性清理、并发标记等技术显著减少停顿时间,提升用户体验。

7. 内存泄漏与避免

  • 常见原因
    • 未释放的全局变量、闭包、未清理的定时器或事件监听器。
  • 避免方法
    • 及时释放不再使用的对象引用。
    • 使用工具(如 Chrome DevTools)监控内存使用情况。

8. 总结

V8 的垃圾回收机制通过分代回收、增量标记、并发清理等优化策略,实现了高效的内存管理。理解其工作原理有助于编写高性能的 JavaScript 代码,并避免内存泄漏等问题。


思维导图建议结构:

  1. 分代回收
    • 新生代
    • 老生代
  2. 回收算法
    • Scavenge
    • Mark-Sweep
    • Mark-Compact
  3. 优化策略
    • 增量标记
    • 惰性清理
    • 并发标记
  4. 内存限制与触发条件
  5. 性能问题与改进
  6. 内存泄漏与避免

希望这份整理内容能帮助你更好地理解 V8 垃圾回收机制,并制作出清晰的思维导图!