js的内存泄露
Posted idzswi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js的内存泄露相关的知识,希望对你有一定的参考价值。
转:https://developer.mozilla.org/zh-CN/docs/Web/javascript/A_re-introduction_to_JavaScript
使用闭包的一个坏处是,在 IE 浏览器中它会很容易导致内存泄露。JavaScript 是一种具有垃圾回收机制的语言——对象在被创建的时候分配内存,然后当指向这个对象的引用计数为零时,浏览器会回收内存。宿主环境提供的对象都是按照这种方法被处理的。
浏览器主机需要处理大量的对象来描绘一个正在被展现的 html 页面——DOM 对象。浏览器负责管理它们的内存分配和回收。
IE 浏览器有自己的一套垃圾回收机制,这套机制与 JavaScript 提供的垃圾回收机制进行交互时,可能会发生内存泄露。
在 IE 中,每当在一个 JavaScript 对象和一个本地对象之间形成循环引用时,就会发生内存泄露。如下所示:
function leakMemory() { var el = document.getElementById(‘el‘); var o = { ‘el‘: el }; el.o = o; }
这段代码的循环引用会导致内存泄露:IE 不会释放被 el
和 o
使用的内存,直到浏览器被彻底关闭并重启后。
这个例子往往无法引起人们的重视:一般只会在长时间运行的应用程序中,或者因为巨大的数据量和循环中导致内存泄露发生时,内存泄露才会引起注意。
不过一般也很少发生如此明显的内存泄露现象——通常泄露的数据结构有多层的引用(references),往往掩盖了循环引用的情况。
闭包很容易发生无意识的内存泄露。如下所示:
function addHandler() { var el = document.getElementById(‘el‘); el.onclick = function() { el.style.backgroundColor = ‘red‘; } }
这段代码创建了一个元素,当它被点击的时候变红,但同时它也会发生内存泄露。为什么?因为对 el
的引用不小心被放在一个匿名内部函数中。这就在 JavaScript 对象(这个内部函数)和本地对象之间(el
)创建了一个循环引用。
这个问题有很多种解决方法,最简单的一种是不要使用 el
变量:
function addHandler(){ document.getElementById(‘el‘).onclick = function(){ this.style.backgroundColor = ‘red‘; }; }
另外一种避免闭包的好方法是在 window.onunload
事件发生期间破坏循环引用。很多事件库都能完成这项工作。注意这样做将使 Firefox 中的 bfcache 无法工作。所以除非有其他必要的原因,最好不要在 Firefox 中注册一个onunload
的监听器。
以上是关于js的内存泄露的主要内容,如果未能解决你的问题,请参考以下文章