JS在创建变量的同时自动分配内存,在不使用这些变量的时候将内存自动释放,这个释放的过程叫做垃圾回收。
内存的三个生命周期:分配、使用、释放
1、分配:变量值的初始化、new一个对象实例、获取一个DOM元素等等都存在分配内存的过程
2、使用:写入和读取内存的过程,例如给变量赋值、获取变量的值
3、释放:垃圾回收机制(无法判断哪一块内存不再被需要,因此释放内存时可能会出现混乱)
由于无法直接判断哪些内存不被需要,因此需要人为给定一些限制条件:
方式一:如果某个对象从未被引用,就要被回收释放;反之,就不会被释放
缺陷:存在循环引用的对象永远不会被释放,例如o和o2相互引用,即便函数结束,也不会被释放
function f(){
var o = {};
var o2 = {};
o.a = o2; // o 引用 o2
o2.a = o; // o2 引用 o
return "azerty";
}
f();
方式二:如果某个对象不能被获取,就要被回收释放,反之,不会被释放
从全局对象开始,查找全局对象引用的对象,对象引用的其他对象...经过这样一系列的查找,将所有对象分为可获得的对象和不能获得的对象,这个过程叫做标记-清除算法。这个方式解决了循环引用对象无法释放的问题,例如上面例子,当函数结束后,再从全局对象开始查找被引用的对象则无法查找到函数中的对象,这时,函数中声明的对象会随着函数的结束被回收释放。
至今所有的垃圾回收机制都是基于标记-清除算法。