ZDecode
Javascript

垃圾回收

JavaScript 的垃圾回收(Garbage Collection, GC)机制是自动内存管理的一部分,用于清除不再使用的对象,释放内存,防止内存泄漏。

一、基本概念

内存生命周期:

  • 分配:创建变量或对象。

  • 使用:读写变量或调用函数。

  • 释放:变量不再可访问时,自动回收内存。

二、主要垃圾回收算法

  1. 标记清除(Mark-and-Sweep) — 主流浏览器使用

核心思想:对象是否“可达”(reachable)?

  • 可达对象:

    • 从根(如全局对象 window、当前执行栈中的变量)出发,能访问到的对象。
  • 不可达对象:

    • 没有引用链指向它了,会被 GC 回收。
function demo() {
  let obj = { name: 'demo' }; // obj 可达
  // ...
} // 离开作用域后 obj 不可达,会被回收
  1. 引用计数(已不推荐独立使用)

每个对象有一个“引用计数”,为 0 时被回收。

  • 缺点:无法处理循环引用(两个对象互相引用,但整体已不可达)
let a = {};
let b = {};
a.ref = b;
b.ref = a; // 即使 a 和 b 不再使用,引用计数也不是 0,无法回收

现代引擎(如 V8)不会单独使用引用计数,而是配合使用。

三、现代垃圾回收机制(以 V8 为例)

V8 的内存划分(简化):

  • 新生代区(Young Generation):存放短生命周期对象

  • 老生代区(Old Generation):存放长生命周期对象

回收策略:

  • 新生代使用 Scavenge 算法(复制 + 标记)

  • 老生代使用 标记清除 + 标记整理 + 增量标记

注意事项

虽然 GC 是自动的,但开发者应:

  • 避免内存泄漏(如下场景):

    • 全局变量未清理

    • 闭包引用未释放

    • DOM 引用未断开

    • setInterval/setTimeout 未清除

  • 使用浏览器 DevTools(如 Chrome 的 Memory 面板)观察内存变化和泄漏情况