内存泄露

一、什么是内存泄漏?

JavaScript中的内存泄漏就是被分配的内存没有被使用,但是也不能被回收的一种现象。

二、内存泄漏会导致的问题?

这样导致内存一直被占用,最后影响程序性能甚至出现崩溃。

三、JavaScript内存泄漏的几种情况。

1、js对象循环引用导致内存泄漏:

function fn1(){
  obj_a = obj_b;
  obj_b.attr = obj_a;
}
function fn2(){
  obj_c = {};
  obj_c.attr = obj_c;
}

上面是两个很明显的循环引用,IE中产生了内存泄露,由于IE的内存回收机制,导至会长期占用内存而不能释放。

2、js对象与dom对象循环引用导致内存泄漏:

var obj = document.getElementById("element");
obj.onclick = function(){
   console.log('js对象与dom对象循环引用导致了内存泄漏');
};

obj引用了dom对象(id为element),obj的一个属性(onclick)又引用了一个匿名函数,在window全局作用域下的变量obj对匿名函数都是可见的,所以obj.onclik也间接的引用了obj对象本身,而且dom对象element是html元素,始终存在,所以obj.onclick还引用了一个始终存在在内存中的dom对象,这样造成内存无法释放,导致内存泄漏。

3、闭包导致的内存泄漏:

function fn3(){
  var js_obj = document.getElementById('box');
  js_obj.oncontextmenu = function(){
    return false;
  }
}

从表面上看,没有任何循环引用。但上面是一个闭包,根据闭包的特性,内部函数有权访问外部函数的变量对象。所以当fn3()执行之后,js_obj是一个DOM元素的引用,DOM元素它长期在网页当中,不会消失,而这个DOM元素的一属性oncontextmenu,又是内部的函数引用(闭包),而这个匿名函数又和js_obj之间有隐藏的关联(作用域链)。所以形成了一个,循环引用,即:

js_obj.oncontextmenu 间接引用到 js_obj,也就是说,这个对象的一个属性,又间接的引用了自己,只要有循环引用,就会在IE下产生内存泄露。

四、解决内存泄漏最好的方法:

虽然浏览器自带多种js内存垃圾回收机制,但是这几种垃圾回收机制都不能及时的实现垃圾回收,所以需要我们手动设置:

function fn3(){
  var js_obj = document.getElementById('box');
  js_obj.oncontextmenu = function(){
    return false;
  }
  js_obj.oncontextmenu = null;
}

看到以上代码,js_obj.oncontestmenu执行完它的任务之后,手动给它赋值一个空值null,这样就完美解决了内存不能及时回收的问题。

posted @ 2018-08-09 16:21  L_mj  阅读(225)  评论(0编辑  收藏  举报