JavaScript 内存管理是如何工作的?

1. 开场白:看不见的房间管家

写 JS 的你我,几乎从不手动 malloc/free,但这不代表内存管理"不存在"。

JavaScript 引擎就像一位房间管家:

  • 你买东西(创建变量)→ 管家帮你找空位;
  • 你用完扔一边(解除引用)→ 管家扫进垃圾桶;
  • 你若一直占着茅坑不拉屎(内存泄漏)→ 管家也无可奈何。

理解管家的工作方式,才能让应用不爆内存、不卡顿、不 OOM。


2. 两张图看懂"东西"放哪儿

存储区域 放什么 特点 生命周期
Stack 栈 原始值(number、boolean、undefined、null、string、symbol、bigint) 固定大小、后进先出、超快 函数 return 即自动弹栈
Heap 堆 引用值(Object、Array、Function、Date、RegExp...) 动态大小、可按引用共享、稍慢 靠垃圾回收器(GC)稍后清理

代码示例

js 复制代码
let age  = 18;        // 栈
let user = {age};     // 栈里只存指针,实际对象在堆

3. 垃圾回收三部曲

现代引擎默认采用**"标记-清除"(Mark-and-Sweep)算法,配合"分代回收"**优化。

3.1 标记阶段(Mark)

从一组**根(Roots)**出发:

  • 当前调用栈里的局部变量;
  • 全局对象(window、globalThis);
  • 被 Chrome DevTools 断点 Hold 住的变量...

把所有能访问到的对象打上 "在用" 标签,其余都是 "垃圾"。

3.2 清除阶段(Sweep)

线性扫堆,把没标签的对象直接释放;

内存空隙由空闲链表 或按页压缩整理,避免碎片化。

3.3 分代优化(Generational GC)

V8 把堆再细分为:

  • 新生代 (1~8 M):短命对象,采用 Scavenge(复制回收),频率高、停顿短;
  • 老生代 :多次幸存的大对象、长寿命对象,采用 Mark-Sweep + Mark-Compact,频率低、停顿长。

实测:95% 的对象 20ms 内就死,分代后 GC 吞吐量提升 5~10 倍。


4. 四种常见内存泄漏与排查清单

泄漏场景 代码味道 修复要点
1. 意外全局变量 function f(){ leaky="oops" } 'use strict' + ESLint no-undef
2. 忘记清理定时器 setInterval(()=>{...},1000) const t=setInterval(...); 卸载时 clearInterval(t)
3. 闭包捕"大"不放 return ()=>console.log('hi') 却捕获了 new Array(1e6) 只把必要变量闭进去,或手动 largeData=null
4. 游离 DOM + 监听器 removeChild(node) 后仍保留 node 引用 node.remove(); node=null; 同时 off() 监听器

5. 开发者必备:Chrome DevTools 三板斧

  1. Performance Monitor
    实时折线图:JS heap size、DOM 节点、事件监听器数量。
  2. Heap Snapshot
    对比两次快照,按 "Retained Size" 排序,轻松找出"大胃王"。
  3. Allocation Timeline
    录制 30 秒用户操作,蓝色竖线表示新生代分配,峰值即潜在泄漏点。

6. 进阶:WeakMap / WeakRef 让 GC 更聪明

  • WeakMap 只保存弱引用,键对象被回收时,映射条目自动消失;
  • WeakRef 允许你观察对象是否已被 GC,而不阻止其被回收;
  • 适合缓存、DOM 元数据映射,不增加额外可达路径。

7. 一句话总结

JavaScript 帮你扫地,但别把垃圾藏到床底 ------

理解栈/堆、标记-清除、分代模型,善用 DevTools,远离四种泄漏,

你的页面才能常驻 60 FPS、不爆 256 M 低端机。


8. 延伸阅读

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄3 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端