1.垃圾回收
对于开发者来说,JavaScript 的内存管理是自动的、无形的。我们创建的原始值、对象、函数……这一切都会占用内存。
可达性(Reachability)
JavaScript 中主要的内存管理概念是 可达性。
简而言之,“可达”值是那些以某种方式可访问或可用的值。它们一定是存储在内存中的。
-
这里列出固有的可达值的基本集合,这些值明显不能被释放。
比方说:
- 当前执行的函数,它的局部变量和参数。
- 当前嵌套调用链上的其他函数、它们的局部变量和参数。
- 全局变量。
- (还有一些内部的)
这些值被称作 根(roots)。
-
如果一个值可以通过引用链从根访问任何其他值,则认为该值是可达的。
比方说,如果全局变量中有一个对象,并且该对象有一个属性引用了另一个对象,则 该 对象被认为是可达的。而且它引用的内容也是可达的。
在 JavaScript 引擎中有一个被称作 垃圾回收器 的东西在后台执行。它监控着所有对象的状态,并删除掉那些已经不可达的。
垃圾回收算法:
JavaScript具有自动垃圾收集机制,也就是说,执行环境将负责管理代码执行过程中使用的内存。
在JavaScript中,如果一个对象不再被引用,那么这个对象就会被垃圾回收器回收,当对象被回收之后,这块内存就可以被再次使用。
JavaScript有两种垃圾回收机制:
1. 标记清除(Mark-and-sweep):这是JavaScript中最常见的垃圾收集方式,当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。
2. 引用计数(Reference counting):引用计数是另一种垃圾回收策略,引用计数的含义是跟踪每个值被引用的次数。当声明了一个变量并将一个引用类型值赋值给该变量时,这个值的引用次数就是1。如果同一个值又被赋值给另一个变量,那么这个值的引用次数就增加了1。相反,如果包含对这个值引用的变量又取得了另外一个值,那么这个值的引用次数就减少1。当这个值的引用次数变为0时,说明没有办法访问这个值了,因此就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次运行时,它就会释放那些引用次数为0的值所占用的内存。
这两种方式都有自己的优缺点,但标记清除是目前主流的垃圾回收方式,主要的原因是它不会导致循环引用的问题。