JavaScript是具有垃圾自动收集机制的。
垃圾收集的原理【找出那些不再继续使用的变量然后释放其占用的内存!】
垃圾收集齐会按照固定的时间间隔周期性的去执行这一操作,萌芽觉得挺有趣的虽然这些知识在我们平常开发中并不常用但是还是需要去了解的!了解垃圾回收能的帮助我们编写代码提升性能以及避免造成不再使用的循环引用对象内存无法回收问题。
- 标记清除 (常见)
- 引用计数
标记清除
垃圾收集分为两种方式,第一种比较常见现在各大浏览器用的都是第一种方式,垃圾收集器在运行时先把所有的变量都做上标记,之后他会去掉环境中的变量引用的的变量的标记,在之后再次被加上标记的变量将被视为准备删除的变量。(原因:环境中的变量无法访问到这些变量了)最后垃圾收集器完成清除工作,销毁带有标记的值并回收他们所占用的内存空间。
通俗点来讲就是先把所有的都打上标记,然后把需要用到的变量的标记解除掉,在之后被打上标记的变量就代表没作用的变量这些变量将被清除内存销毁掉。
目前各大浏览器都采用这种方式就是垃圾收集时间的间隔有所不同罢了。
引用计数
萌芽觉得这个策略有点尴尬,容易出BUG所以不太常用。引用计数的表示跟踪记录每个值被引用的次数,当声明一个变量并将一个引用类型赋值给该变量时,则这个值引用的变量又取得了应外一个值,则这个值的引用次数减一,当这个值的引用次数变成0的时候则说明没有办法在访问这个值了,因而就可以将其占用的内存空间回收回来。
萌芽理解就是说new 一个对象把它赋给一个变量的时候引用为1,这个时候再去声明一个对象然后把他的引用指向这个变量那么这个变量之前引用的对象则为0,为0的引用就会被释放占用内存。
但是刚刚我们也说到这个是有BUG的,比如当一个两个对象互相引用……
function demo() {
var objA = new Object(),
objB = new Object();
objA.addObj = objB;
objB.addObj = objA;
}
因为他们的引用次数永远都不可能为0这种情况下就会发生永远无法回收的问题!如果这个函数再被重复调用就会发生大量内存无法回收!
可怕的是COM(组建对象模型)对象的垃圾收集机制就是采用技术策略,你可能就问我COM和我们有关系吗?其实我们的BOM和DOM中对象就是使用COM对象的形式来实现的!!!只要IE中涉及COM对象,就会存在循环引用问题:
var element = document.getElementById('div'),
myObject = new Object();
myObject.element = element;
element.someObject = myObject;
为了避免这种循环引用问题,最好是在不使用他们的时候给他们断开链接!
myObject = null;
element = null;
设为 null 意味着切断之前的链接当垃圾收集器下次执行的时候就会删除他们占用的内存啦,用null来释放引用这种方式叫做解除引用。
解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收哦!
--------------------------------------------------------------------------------- 【 小知识 】
事实上有的浏览器也能触发垃圾收集过程:
IE:window.CollectGarbage()
Opera:window.opera.collect()