Javascript中的垃圾回收机制

javascript具有自动垃圾收集机制,会自行管理内存分配及无用内存的回收,也就是说,执行环境会负责管理代码执行过程中使用的内存。原理:找出那些不再继续使用的变量,然后释放其占用的内存.由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。JavaScript的解释器可以检测到何时程序不再使用一个对象了,当他确定了一个对象是无用的时候,可以把它所占用的内存释放掉了。

var a = "before";
var b = "override a";
var a = b; //这段代码运行之后,before字符串失去了引用(之前是被a引用),系统检测到这个事实之后,就会释放该字符串的存储空间.

垃圾回收方式:

现在各大浏览器通常采用的垃圾回收有两种办法:标记清除,引用计数.

  1. 标记清除,垃圾收集器会在运行的时候给存储在内存中的变量加上标记,然后它会去掉环境中正在使用的变量的标记,而没有被去掉标记的变量将被视为准备删除的变量,最后,垃圾收集器完成内存清理工作,销毁那些带标记的值并回收它们所占用的内存空间。
  2. 另一种不太常见的垃圾收集策略叫做引用计数.引用计数的含义是跟踪记录每个值被引用的次数,引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1。当这个值的引用次数变为0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收起来.但这种方法有严重的问题:比如循环引用(对象A中包含一个指向对象B的指针,而对象B中也包含一个指向对象A 的引用)导致的引用次数永远不会是0.
function problem() {
     var objA = new Object();
     var objB = new Object();
     objA.someOtherObject = objB;
     objB.anotherObject = objA;
}//objA和objB通过各自的属性相互引用;也就是说这两个对象的引//用次数都是2。

IE中有一部分对象并不是原生JavaScript对象。例如,其BOM和DOM中的对象就是使用C++以COM(组件对象)对象的形式实现的,而COM对象的垃圾回收器就是采用的引用计数的策略。因此,即使IE的Javascript引擎使用标记清除的策略来实现的,但JavaScript访问的COM对象依然是基于引用计数的策略的。可以手动切断他们的循环引用。

myObj.element = null;
element.someObject =null;

减少javascript的垃圾回收:

new关键字意味着一次内存分配;{}创建一个新对象,[]创建一个新数组,function(){}创建一个新方法.最好的解决方法:
在初始化的时候新建,在后续过程中尽可能多的重用.

对象{}优化:

  1. 避免使用{}来新建对象,{}新建的带属性的对象,常常作 为方法的返回值来使用.最好的解决方法是:每一次函数调用完成之后,将需要返回的数据放入一个全局的对象中,并返回全部对象.
  2. 遍历对象的所有属性,并逐个删除,最终将对象清理为一个空对象.再添加新的属性来达到重复利用.

数组array优化:

将数组长度赋值为0清空数组.

方法function优化:

要是动态创建方法的地方,就有可能产生内存垃圾.

//将方法作为返回值,就是一个动态创建方法的实例.解决方法:可以将返回值作为方法保存起来
this.tickFunc = (
    function(self) {
      return function() {
                self.tick();
      };
    }
)(this);
setTimeout(this.tickFunc, 16);

垃圾收集器是周期性运行的,会导致整个程序的性能问题。javascript在进行内存管理和垃圾收集时面临的一个主要问题就是分配给Web浏览器的可用内存数量通常比分配给桌面应用系统的少,一般来说,这样做的目的主要是出于安全方面的考虑,目的是防止运行javascript的网页耗尽全部系统内存而导致系统崩溃.内存限制问题不仅会影响变量分配内存,同时还会被影响调用栈以及在一个线程中能够同时执行的语句数量.因此确保占用最少的内存可以让页面获得更好的性能,而优化内存的最佳方案就是为执行中的代码只保存必要的数据,一旦数据不再有用,那么就将其设置为null来释放引用,这个做法叫做解除引用,适用于大多数全局变量和全局函数(内置对象除外),局部变量会在离开执行环境时自动被解除引用.解除引用的真正作用是让值脱离执行环境,以便垃圾收集器再次运行的时将其回收.

猜你喜欢

转载自blog.csdn.net/wsln_123456/article/details/84344880