js的垃圾收集机制

js中的垃圾收集:标记清除和引用计数(主流是标记清除)


  1. 垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量及被环境中的变量引用的变量的标记。而在此之后再被加上离开环境时标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了,最后,垃圾收集器完成内存的清除工作。销毁哪些带标记的值,并回收他们所占用的内存空间。

  2. 引用计数的含义是跟踪记录每个值被引用的次数。当一个变量引用了另一个变量的时候,则这个值就会加1,如果一个变量又赋值给了另外一个变量,则再加1.相反如果又没有引用这个值的变量了,那么会减1.当这个值的引用次数为0时,则说明没有办法在访问这个值了,因而可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再执行时,它就会释放那些引用次数为零的值所占用的内存。

     

    引用计数有个严重的bug---循环引用。即A对象中包含一个指向对象B的指针,而对象B中也包含一个指向对象A的引用。

    function problem(){
		var objectA = new Object();  //objectA为该new Object实例的第一次引用 ,引用+1
		var objectB = new Object();   //objectB为该new Object实例的第一次引用,引用+1
		objectA.a = objectB;  //objectA.a为objectB所引用实例的的第二次引用,引用+1
		objectB.b = objectA;  //objectB.b为objectA所引用实例的的第二次引用,引用+1
 
        objectA = null; //ObjectA对象的引用-1
        objectB = null;//ObjectB对象的引用-1
 
        //但是ObjectA 和 ObjectB俩个对象仍然还有一次引用
        //引用不是0,垃圾回收器就无法回收他们
        // 所以这就循环引用所带来的问题
    }

 两个对象的属性相互引用,即这两个对象的引用次数都是2。

在采用标记清除策略的实现中,当函数执行完毕后,两个变量还继续存在,因为它们的引用次数永远都不会是0.假如这个函数被重复多次调用,就会导致大量内存得不到回收。

因此现在的主流策略是标记清除。

 

你可能感兴趣的:(Javascript,浏览器,javascript)