Skip to content

Javascript内存管理与V8引擎垃圾回收机制详解 🚀 ​

内存在JavaScript中的存储方式 💾 ​

  1. 栈内存(Stack)存储:

    • 存储基本数据类型:Number、String、Boolean、Null、Undefined、Symbol、BigInt
    • 存储对象的引用地址
    javascript
    let number = 42;           // 存储在栈中
    let string = "Hello";      // 存储在栈中
  2. 堆内存(Heap)存储:

    • 存储引用数据类型:Object、Array、Function等
    javascript
    let obj = { name: "张三" };  // 对象存储在堆中,引用地址在栈中
    let arr = [1, 2, 3];        // 数组存储在堆中,引用地址在栈中

V8引擎内存限制 🔧 ​

  1. 内存上限:

    • 64位系统:约1.4GB
    • 32位系统:约700MB
  2. 为什么要设置内存限制?

    • 防止JavaScript占用过多系统内存
    • 垃圾回收时的性能考虑(回收1.4GB比回收4GB快得多)
    • Web场景下通常够用

V8的分代回收机制 ♻️ ​

新生代(Young Generation)👶 ​

  • 特点:

    • 存储生命周期短的对象
    • 64位系统下约32MB,32位系统下约16MB
    • 使用Scavenge算法(复制算法)
  • 回收过程:

    From Space        To Space
    [活跃对象] ------> [复制]
    [垃圾对象]        [空]
    1. 将活跃对象复制到To Space
    2. 清空From Space
    3. 交换From Space和To Space

老生代(Old Generation)👴 ​

  • 特点:

    • 存储生命周期长的对象
    • 占据大部分内存空间
  • 回收算法:Mark-Sweep-Compact(标记-清除-整理)

    1. 标记阶段:标记活跃对象
    2. 清除阶段:清除未标记对象
    3. 整理阶段:整理内存碎片

对象晋升机制 🆙 ​

对象从新生代晋升到老生代的条件:

  1. 对象经过一次Scavenge回收依然存活
  2. To Space空间使用率超过25%

常见内存泄漏及优化建议 ⚠️ ​

1. 全局变量 ​

js
// 不推荐
window.user = { name: "张三" };
// 推荐
let user = { name: "张三" };
// 使用完后
user = null;

2. 闭包使用 ​

javascript
// 可能导致内存泄漏
function createCache() {
  const cache = {};
  return {
    set: (key, val) => cache[key] = val,
    get: key => cache[key]
  };
}

// 建议在不需要时手动解除引用
const cache = createCache();
// 使用完后
cache = null;

3. 事件监听器 ​

javascript
// 记得移除不需要的事件监听
element.addEventListener('click', onClick);
// 不用时移除
element.removeEventListener('click', onClick);

Node.js特殊配置 🛠️ ​

手动触发垃圾回收 ​

javascript
global.gc();  // 需要添加 --expose-gc 参数启动

内存配置 ​

bash
# 配置老生代内存上限
node --max-old-space-size=4096 app.js

# 配置新生代内存上限
node --max-new-space-size=2048 app.js

性能监控建议 📊 ​

  1. 使用Chrome DevTools的Memory面板监控内存使用
  2. 定期使用Performance面板检查内存泄漏
  3. 在Node.js中使用process.memoryUsage()监控内存使用情况

最佳实践总结 ✨ ​

  1. 及时释放不用的引用
  2. 避免过多的全局变量
  3. 谨慎使用闭包
  4. 及时清理定时器和事件监听
  5. 大型对象尽可能复用
  6. 注意避免内存泄漏的代码模式