必要性:由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JS 程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则JS 的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。
标记清除
这是最常见的垃圾回收方式,当变量进入环境时,就标记这个变量为“进入环境”,从逻辑上讲,永远不能释放进入环境变量所占用的内存,只要执行流程进入相应的环境,就可能用到他们。当离开环境时,就标记为离开环境。
垃圾回收器在运行的时候会给存储在内存中的变量都加上标记(所有都加),然后去掉环境变量中的变量,以及被环境变量中的变量所引用的变量(条件性去除标记),删除所有被标记的变量,删除的变量无法在环境变量中被访问,所以会被删除,最后垃圾回收器,完成了内存的清除工作,并回收他们所占用的内存。
计数引用
用引用计数法会存在内存泄漏。
function problem() {
var objA = new Object()
var objB = new Object()
objA.someOtherObject = ojbB
objB.anotherObject = objA
}
在这个例子里面,objA 和objB 通过各自的属性相互引用,这样的话两个对象的引用次数都为2,在采用引用计数的策略中,由于函数执行后,这两个对象都离开了作用域,函数执行完成之后,因为计数不为0,这样的相互作用如果大量存在就会导致内存泄漏。
特别是在DOM 对象中,也容易存在这种问题:
// 不会有垃圾回收的过程
var element = document.getElementById(' ')
var myObj = new Object()
myObj.element = element
element.someObject = myObj