一、什么是内存泄漏?
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,这样就完美解决了内存不能及时回收的问题。