JavaScript内存管理依赖垃圾回收机制,核心为标记-清除算法,通过根对象判断可达性,回收不可达对象;V8引擎采用分代回收与增量标记优化性能,避免循环引用问题,开发者需注意解除DOM引用、清除定时器等以防止内存泄漏。

JavaScript的内存管理是开发者无需手动干预的部分,尤其在现代应用开发中,理解其背后的垃圾回收机制有助于写出更高效、不易出问题的代码。JavaScript引擎会自动分配和释放内存,而这个过程的核心就是垃圾回收(Garbage Collection, GC)。
内存分配与生命周期
当变量被创建时,JavaScript会为其分配内存。例如:
let user = { name: "Alice" };let age = 25;
这些值存储在堆内存中。变量的生命周期从声明开始,到不再被引用为止。一旦变量无法被访问,它所占用的内存就成为“垃圾”,等待回收。
关键点在于:可达性(reachability)。JavaScript通过根对象(如全局对象、调用栈中的变量等)判断一个对象是否可达。如果一个对象无法从根节点访问,则被视为不可达,可被回收。
立即学习“Java免费学习笔记(深入)”;
主流垃圾回收算法:标记-清除
目前大多数JavaScript引擎(如V8)使用的是标记-清除(Mark-and-Sweep)算法。
- 引擎从根对象开始遍历所有可达对象,并给它们打上“标记”
- 接着清理未被标记的对象,释放其内存
- 整个过程周期性执行,或在内存压力较大时触发
这种机制能有效处理循环引用的问题,相比早期的引用计数更加可靠。
引用计数及其局限
另一种常见的方法是引用计数(Reference Counting),每当一个对象被引用,其引用数加1;引用解除则减1。当计数为0时,立即回收。
但它有一个致命缺陷:无法处理循环引用。
let obj1 = {};let obj2 = {};
obj1.ref = obj2;
obj2.ref = obj1; // 循环引用
即使这两个对象已不再使用,引用计数仍为1,无法被回收。因此现代引擎已不再依赖此方式作为主要策略。
优化策略:分代回收与增量GC
V8引擎采用分代回收(Generational Collection)来提升效率。它基于一个观察:大多数对象生命周期很短。
- 新生代(Young Generation):存放短期对象,频繁进行小规模GC
- 老生代(Old Generation):长期存活对象移入此处,GC频率较低
同时,为了减少主线程阻塞,V8还引入了增量标记(Incremental Marking)和并发回收(Concurrent Sweeping),让GC任务分片执行,避免长时间停顿。
基本上就这些。虽然开发者不直接管理内存,但避免内存泄漏依然重要。比如及时解除DOM引用、清除定时器、避免意外的全局变量等。理解垃圾回收机制,能帮助你写出更健壮的应用。










