JavaScript内存生命周期分分配、使用、释放三阶段:分配由引擎自动完成,原始值存栈、对象存堆;使用中引用决定对象存活,全局变量、闭包、事件监听器等易致内存滞留;释放依赖标记-清除GC,需手动断开引用以助回收。

JavaScript 的内存生命周期分为三个阶段:分配、使用和释放。开发者通常不直接控制内存分配和释放,但理解这些阶段有助于写出更健壮、低内存泄漏风险的代码。
内存分配:引擎自动完成,但方式影响后续行为
当你声明变量、创建对象或调用函数时,JavaScript 引擎(如 V8)会在堆(heap)或栈(stack)中为其分配内存。
- 原始值(string、number、boolean、null、undefined、symbol、bigint)一般分配在栈中,复制时是值拷贝
- 对象(包括数组、函数、日期、正则、Promise 等)分配在堆中,变量保存的是指向堆内存的引用
- 注意:频繁创建大型对象(如大数组、长字符串拼接)会加速堆内存增长,可能触发更频繁的垃圾回收
内存使用:引用关系决定“存活”状态
只要一个对象还能被代码中的某个变量、闭包、全局属性或 DOM 引用链访问到,它就被视为“可达”,不会被回收。
- 全局变量始终可达,其引用的对象长期驻留内存
- 闭包会捕获外层作用域的变量,若不小心保留了大对象引用,就可能造成隐式内存滞留
- 事件监听器、定时器回调、未清理的 Promise 链等,都可能意外维持对对象的引用
- 例子:
element.addEventListener('click', handler)后忘记removeEventListener,且handler引用了大对象 → 该对象无法释放
内存释放:依赖垃圾回收机制,但需主动断开引用
JavaScript 使用自动垃圾回收(GC),主流引擎采用“标记-清除”(Mark-and-Sweep)算法。GC 不会立即运行,而是在合适时机扫描并回收不可达对象。
立即学习“Java免费学习笔记(深入)”;
- 显式帮助 GC 的方式是:将不再需要的引用设为 null、undefined 或重新赋值(尤其对全局/长生命周期对象)
- 移除 DOM 元素前,手动解绑事件监听器、清空数据缓存、中断定时器(
clearTimeout/clearInterval) - 避免循环引用(尤其在旧版 IE 中严重),现代引擎能处理大部分 JS 层循环引用,但结合 DOM 仍可能出问题
- 可借助 Chrome DevTools 的 Memory > Heap snapshot 对比前后快照,识别未释放的对象及其引用链








