JavaScript 垃圾回收机制
1. JavaScript 垃圾回收机制的思想很简单:确定哪个变量不会再被使用,然后释放它所占用的内存空间,垃圾回收程序每隔一段时间就会自动运行一次。但是我们需要对变量进行跟踪,标记不会再使用的变量。
2. 浏览器史上两种主要的标记策略:
(1)标记清理:是 JavaScript 最常用的垃圾回收策略,当变量进入一个执行上下文时,它会被打上一个“处于上下文”的标记,当它离开此执行上下文时,它会被打上一个“离开上下文”的标记。当垃圾回收程序运行时,会标记内存中存储的所有变量,然后将处于上下文的变量的标记清除掉,在此之后,仍然有标记的变量则会被垃圾回收程序进行内存清理,销毁并回收它们的内存。
(2)引用计数:此种策略不太常用,其思想为对每个值记录它被引用的次数。当一个变量被另一个变量引用着时,它的引用数+1,当保存对该变量引用的变量被其他值覆盖时,引用数-1。那么当一个变量的引用数为0时,说明程序不会再用到它,垃圾回收程序就会清理掉这个变量。当时这种策略存在某些问题:在两个变量循环引用时,即 A 引用 B,而 B 又引用 A 时,那它们两个永远都不会被回收。
function problem() {
let objectA = new Object();
let objectB = new Object();
objectA.someOtherObject = objectB;
objectB.anotherObject = objectA;
}
这段代码在标记清理策略中没有问题,因为函数结束后,它们所处的执行上下文销毁,因此这两个对象不在任何上下文中,可以被回收。但在引用计数时,不会被回收掉,如果此函数重复执行,那么会有大量内存无法被回收。
3. 垃圾回收周期的合理制定:垃圾回收程序会每隔一段时间执行一次,那么隔多久执行一次合适是一个值得思考的问题。在早期,IE 浏览器策略是根据变量分配的个数,来执行垃圾回收程序,如果内存中变量的个数过多,超过某个阈值,则垃圾回收机制运行。但有这样一种情况,即声明了那么多变量,而且那些变量都有用处,那么 IE 这种做法会导致垃圾回收机制频繁运行,因为即使运行了也不会清理有用的变量,而有用的变量数目又超过了阈值。后来,策略改为:检测一次垃圾回收机制运行后回收了多少内存,如果回收的内存过少,则将阈值翻倍,如果有一次回收内存超过已分配的85%,则将阈值还原为默认值。
4. 内存管理:

浙公网安备 33010602011771号