js的内存泄露

转:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScriptjavascript

使用闭包的一个坏处是,在 IE 浏览器中它会很容易致使内存泄露。JavaScript 是一种具备垃圾回收机制的语言——对象在被建立的时候分配内存,而后当指向这个对象的引用计数为零时,浏览器会回收内存。宿主环境提供的对象都是按照这种方法被处理的。java

浏览器主机须要处理大量的对象来描绘一个正在被展示的 HTML 页面——DOM 对象。浏览器负责管理它们的内存分配和回收。浏览器

IE 浏览器有本身的一套垃圾回收机制,这套机制与 JavaScript 提供的垃圾回收机制进行交互时,可能会发生内存泄露。数据结构

在 IE 中,每当在一个 JavaScript 对象和一个本地对象之间造成循环引用时,就会发生内存泄露。以下所示:闭包

function leakMemory() {
    var el = document.getElementById('el');
    var o = { 'el': el };
    el.o = o;
}

这段代码的循环引用会致使内存泄露:IE 不会释放被 el 和 o 使用的内存,直到浏览器被完全关闭并重启后。函数

这个例子每每没法引发人们的重视:通常只会在长时间运行的应用程序中,或者由于巨大的数据量和循环中致使内存泄露发生时,内存泄露才会引发注意。this

不过通常也不多发生如此明显的内存泄露现象——一般泄露的数据结构有多层的引用(references),每每掩盖了循环引用的状况。code

闭包很容易发生无心识的内存泄露。以下所示:对象

function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        el.style.backgroundColor = 'red';
    }
}

这段代码建立了一个元素,当它被点击的时候变红,但同时它也会发生内存泄露。为何?由于对 el 的引用不当心被放在一个匿名内部函数中。这就在 JavaScript 对象(这个内部函数)和本地对象之间(el)建立了一个循环引用。blog

这个问题有不少种解决方法,最简单的一种是不要使用 el 变量:

function addHandler(){
    document.getElementById('el').onclick = function(){
        this.style.backgroundColor = 'red';
    };
}

 另一种避免闭包的好方法是在 window.onunload 事件发生期间破坏循环引用。不少事件库都能完成这项工做。注意这样作将使 Firefox 中的 bfcache 没法工做。因此除非有其余必要的缘由,最好不要在 Firefox 中注册一个onunload 的监听器。

相关文章
相关标签/搜索