垃圾回收机制称Garbage Collection简称GC。js的垃圾回收机制就是定时回收闲置资源的一种机制,每隔一段时间,执行环境都会清理掉内存中一些没用的变量释放他做占用的内存
核心思想:找到没用的变量,释放他们的内存
1)标记清除
标记清除是现在最常使用的垃圾回收策略,使用标记清除作为垃圾回收机制的浏览器,会在垃圾回收程序进行时,有如下步骤:
- 标机内存中所有的变量
- 把在上下文(全局作用域,脚本作用域)中声明的变量,以及在全局被引用的变量的标记删除掉,剩下的所有带标记的变量就被视为要删除的变量,垃圾回收执行时释放他们所占用的内存
- 内存清理,清除垃圾
// 变量 color,dog 在全局环境下声明,不会被清除
const color = 'red';
var dog = '金毛';
{
let cat = 'kitty'; // 变量 cat 在块作用域中声明,且没有被全局所引用,所以会在下一次垃圾回收执行时,释放其内存
}
2)引用计数
引用计数是一种不常用的垃圾回收策略,主要核心思路就是记录值被引用的次数,一个值被赋给变量,引用次数+1,这个变量在某个时刻重新赋了一个新值,旧值的引用次数-1变为了0,在下次垃圾回收程序进行时就会释放他的内存。
引用技术存在的问题:循环引用
function fn() {
const obj1 = new Object()
// new Object 在堆内存中创建了一个对象1 {} 这个值被赋值给obj1 于是引用次数 + 1
const obj2 = new Object()
// new Object 在堆内存中创建了一个对象2 {} 这个值被赋值给obj2 于是引用次数 + 1
obj1.a = obj2; // obj2 被赋值给 obj1的a属性 于是对象1的引用次数 1+1 = 2
obj2.a = obj1; // obj1 被赋值给 obj2的a属性 于是对象2的引用次数 1+1 = 2
}
// 此时两个对象之间相互引用,如函数多次调用,又会重新执行多次函数体,又会多了n个相互引用的对象占用内存
obj1.a = null;
obj2.a = null;
// 通过设置为 null 可以切断两者之间的引用,在下次回收时就会清理释放掉