一,背景:
如果没有垃圾回收机制,javascript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。
由于字符串,数组,对象这些引用类型,给他们分配内存的时候是根据他们的大小进行动态分配的,动态分配的被占用的这些内存,最终都要释放掉以供再次利用。
二,javascript的垃圾回收机制:
来看这个代码:
var a = "abcd"; a = "efgh";
当字符串abcd失去被a的引用时,就该把abcd所占的内存释放掉了。
现在各个浏览器基本常采用标志清除法,和引用计数法来回收垃圾;
1,标记清除法:
当变量进入执行环境时,标记这个变量为“进入环境”;
当变量离开环境时,标记为“离开环境”;
垃圾回收器并不是每时每刻都在工作,每隔一段时间工作一次;
垃圾回收器运行时,给每个变量都加上标记,然后去掉环境中的变量,以及被环境中变量引用的变量的标记。
然后,这时候,剩下的所有的被标记的变量,都是要被清除回收的变量。
最后,垃圾收集器销毁这些变量的值,收回占用的内存空间。
2,引用计数法
跟踪每个值被引用的次数。
当声明了一个变量,把一个引用类型的值复制给这个变量时,这个值的引用次数就是1;
如果这个变量又重新引用了另一个值,那么原先的值引用次数就减1;
当一个值的(被)引用次数变成0时,就说明不再也没有办法再引用这个值了。因此就可以将他的内存释放。
垃圾收集器在下次运行时,就会回收释放掉这种引用次数为0的值的内存。
这种办法存在一种问题:
function problem(){ var obj1 = {}; var obj2 = {}; obj1.obj = obj2; obj2.obj = obj1; }
在这个方法中,两个对象通过各自的name属性相互引用;
函数执行完后,两个对象都会离开作用域,但因为他们的引用次数都无法为0,他们所占的内存就无法被释放掉;
这样的结果是,会造成大量的内存泄漏。
内存泄漏指的是你申请了一块内存,在使用后无法释放已申请的内存空间,
比如程序会认为你可能会用到这个变量,就一直给你留着不释放,一次内存
泄漏可以被忽略,但是内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
上面的问题,我们可以手动解决:
obj1.obj = null;
obj2.obj = null;