JavaScript是一门动态弱类型语言,具有自动垃圾回收机制。这意味着开发者不需要显式地分配和释放内存。但是,了解JavaScript的内存管理机制对于写出高效、稳定的JavaScript代码至关重要。
内存分配
在JavaScript中,变量可以通过以下两种方式声明:
-- -- --- -------- --- ----- - -------- -- -- --- - ----- ----- --- -------- - -------- ----- ---------- - ---
var
和 let
声明的变量都可以被重新赋值,而 const
声明的变量则是只读的。无论使用哪种方式来声明变量,在JavaScript中,所有变量最终都存储在内存中。
当我们声明一个变量时,JavaScript引擎会为该变量分配内存。在ES6之前,这些变量的内存分配是由堆栈模型控制的。在堆栈模型中,以函数为单位来处理内存,每个函数都有自己的作用域和内存空间。但是,从ES6开始,JavaScript引入了新的内存管理机制:标记清除和引用计数。
标记清除
JavaScript引擎会周期性地检查内存中不再使用的对象(即没有被引用的对象),并释放这些对象所占用的内存。这个过程被称为垃圾回收。
在标记清除机制中,当变量不再存在引用时,它们被标记为可回收的。然后,垃圾回收器就会在未来某个时间回收这些已经标记的变量。
例如:
--- - - - ----- ----- -- --- - - - ----- ------- -- -------- - -- -------- - -- - - ----- - - -----
在上面的代码中,变量 a
和 b
分别引用两个对象。这些对象之间互相引用,形成了一个循环引用。一旦我们把 a
和 b
变量赋值为 null
,这些对象就不再被引用了。此时,JavaScript引擎会启动垃圾回收器,并且检测到这些对象可以被释放。
标记清除机制是目前最常见的垃圾回收机制,因为它对于大多数应用程序都能提供良好的性能。
引用计数
另一种垃圾回收机制是引用计数。在引用计数机制中,每个对象都有一个引用计数器,记录了指向该对象的引用数量。当引用计数器为0时,该对象就被认为是不再使用的,并且可以被垃圾回收器释放。
例如:
--- - - - ----- ----- -- --- - - - ----- ------- -- -------- - -- -------- - -- - - ----- - - -----
在上面的代码中,对象 { name: "Tom" }
和 { name: "Jerry" }
分别有一个引用计数器,记录了变量 a
和 b
对它们的引用次数。当我们把 a
和 b
变量赋值为 null
时,它们对这些对象的引用被删除,所以引用计数器减少到0。
引用计数机制相对于标记清除机制来说是一种较早期的垃圾回收机制,但因为其某些问题(如循环引用),现在不再被广
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/34795