Skip to content

V8垃圾回收机制是Google Chrome浏览器和Node.js中使用的JavaScript引擎的核心部分,它负责自动管理内存,释放不再使用的对象,以避免内存泄漏和溢出。V8采用分代垃圾回收策略,将内存分为 **新生代(Young Generation)**和 老生代(Old Generation),并为这两个区域设计了不同的垃圾回收算法。

1. 新生代垃圾回收(Scavenge)

  • 特点: 新生代用于存储生命周期较短的对象。大多数新创建的对象最初都会分配到新生代中。
  • 空间划分: 新生代进一步划分为两个空间:
    • From 空间: 存储当前活动对象的区域。
    • To 空间: 用于在垃圾回收过程中接收从 From 空间复制过来的存活对象。
  • 垃圾回收算法: 新生代使用Scavenge算法,这是一种复制算法(Copying Algorithm)。该算法的基本思想是:
    1. 活动对象最初存储在 From 空间。
    2. 当触发垃圾回收时,将存活对象从 From 空间复制到 To 空间,并清空 From 空间。
    3. FromTo 空间不断交换角色,确保内存得到有效管理。
  • 晋升(Promotion): 如果对象在 From 空间中经过多次垃圾回收依然存活,或者 To 空间已经占用较大内存,这些对象会被“晋升”到老生代。这种机制避免了频繁回收生命周期较长的对象。

2. 老生代垃圾回收(Mark-Sweep & Mark-Compact)

  • 特点: 老生代用于存储生命周期较长的对象,特别是那些从新生代晋升过来的对象。
  • 垃圾回收算法: 老生代使用了**标记-清除(Mark-Sweep)标记-整理(Mark-Compact)**算法:
    • 标记-清除(Mark-Sweep)
      1. 标记阶段: 遍历对象图,标记所有活动对象(即仍然被引用的对象)。
      2. 清除阶段: 清除未被标记的对象,释放相应的内存。
    • 标记-整理(Mark-Compact)
      1. 标记阶段: 标记所有活动对象。
      2. 整理阶段: 将存活的对象压缩到堆的一端,腾出连续的内存空间,从而减少内存碎片。
  • 并发和增量标记: 为了减少垃圾回收对应用程序的影响,V8 引入了**并发标记(Concurrent Marking)增量标记(Incremental Marking)**技术:
    • 并发标记: 标记阶段与应用程序的执行并发进行,以减少垃圾回收暂停时间。
    • 增量标记: 将标记过程分为多个小步骤,在应用程序执行过程中逐步完成,以避免长时间的暂停。

3. 垃圾回收的触发条件

V8垃圾回收机制会在以下情况下触发:

  • 当内存使用量达到某个阈值时。
  • 当执行耗时的代码时,如执行循环或递归函数时。
  • 当明确调用垃圾回收函数时。

4. 性能优化

为了减少垃圾回收对性能的影响,V8采用了多种优化技术,包括:

  • 增量标记:将垃圾回收过程拆分成多个小步骤,穿插在正常的程序执行过程中。
  • 并行标记:利用多核CPU,同时运行多个回收线程。
  • 惰性清理:在内存足够的情况下,延迟清理操作,让JavaScript脚本先执行。