JavaScript内存生命周期分分配、使用、释放三阶段:分配时基本类型存栈、引用类型存堆;使用时活跃引用阻止回收;释放需主动解绑监听器、清除定时器、置空引用以配合GC。

JavaScript 的内存生命周期分为三个核心阶段:分配、使用和释放。理解这三步,是避免内存泄漏、提升应用性能的关键。
内存分配:引擎自动完成,但方式影响后续行为
当你声明变量、创建对象或调用函数时,JavaScript 引擎会自动为这些值分配内存。
- 基本类型(如 number、string、boolean)直接分配在栈(stack)中,空间小、速度快;
- 引用类型(如 object、array、function)的值存在堆(heap)中,变量本身只存一个指向堆地址的引用;
- 闭包、事件监听器、定时器等隐式持有时,也会触发堆内存分配——这点容易被忽略。
内存使用:读写数据即“活跃引用”
只要某个对象还能通过作用域链、全局变量、DOM 引用、回调函数等方式被访问到,它就被视为“正在使用”,不会被回收。
- 全局变量长期存活,其引用的对象也一直驻留内存;
- DOM 元素被移除后,若 JS 仍保留对它的引用(比如缓存到变量或闭包里),该元素及其子树无法释放;
- 未清理的事件监听器(尤其绑定在 document 或 window 上)会持续持有目标对象。
内存释放:依赖垃圾回收机制,但需主动配合
V8 引擎主要使用标记-清除(Mark-and-Sweep)算法:先标记所有可访问对象,再清除未被标记的部分。但它无法识别“逻辑上已废弃但仍有引用”的情况。
立即学习“Java免费学习笔记(深入)”;
- 及时将不再需要的大对象设为 null(如
largeData = null),有助于 GC 下次扫描时将其回收; - 移除 DOM 元素前,用
removeEventListener解绑对应监听器; - 定时器不用时调用
clearTimeout或clearInterval; - 避免在循环或高频回调中意外创建闭包引用外部大对象。


















