JavaScript 内存泄漏教程 http://www.ruanyifeng.com/blog/2017/04/memory-leak.html
关于释放引用DOM对象内存的问题 https://segmentfault.com/q/1010000004467031
解决内存问题 https://developers.google.com/web/tools/chrome-devtools/memory-problems/?hl=zh-cn
只有页面的 DOM 树或 JavaScript 代码不再引用 DOM 节点时,DOM 节点才会被作为垃圾进行回收。 如果某个节点已从 DOM 树移除,但某些 JavaScript 仍然引用它,我们称此节点为“已分离”。已分离的 DOM 节点是内存泄漏的常见原因。此部分将教您如何使用 DevTools 的堆分析器确定已分离的节点。
JavaScript-内存泄漏问题 http://blog.csdn.net/qiqingjin/article/details/50497438
1. 概念
内存泄漏是指一块被分配的内存,既不能使用,又不能回收,直到浏览器进程结束。
2. 可能导致内存泄漏的几种情况
(1) 当页面中的元素被移除或者替换时,若元素绑定的事件没有被移除,在IE中不会做出处理,应该先移除绑定的事件。
(2) 普通循环引用可能导致内存泄漏:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<html> <body> <scripttype="text/javascript"> document.write("circularreferences between JavaScript and DOM!"); varobj; window.onload= function(){ obj=document.getElementById("DivElement"); document.getElementById("DivElement").expandoProperty=obj; obj.bigString=newArray(1000).join(new Array(2000).join("XXXXX")); }; </script> <divid="DivElement">Div Element</div> </body> </html> |
如上述清单中所示,JavaScript 对象obj
拥有到 DOM 对象的引用,表示为 DivElement
。而 DOM 对象则有到此JavaScript 对象的引用,由expandoProperty
表示。可见,JavaScript对象和 DOM 对象间就产生了一个循环引用。由于 DOM 对象是通过引用计数管理的,所以两个对象将都不能销毁。
(3) 闭包中的循环引用:
1 2 3 4 5 6 7 |
varelem=document.getElementById(‘test’); elem.addEventListener(‘click’,function(){ alter(‘You click’+elem.tagName); }); |
DOM对象在闭包释放之前不会被释放,而闭包作为DOM对象的事件处理函数存在,所以DOM对象释放之前闭包也不会释放。这种情况,即使在DOM 树种把DOM对象删除,由于循环存在,DOM对象和闭包也不会被释放,应该改成 this.tagName;
(4) 闭包中循环引用的另一种情况:
1 2 3 4 5 6 7 8 9 10 11 |
functionbindEvent(){ varobj=document.createElement(‘div’); obj.onclick=function(){ //Even if it’s a emptyfunction }; } |
一个构成闭包的函数对象中某元素绑定某事件,而该元素又是一个活动对象,就会产生一个循环引用。解决:将事件处理函数定义在外部,解除闭包。
(5) 不彻底的销毁对象:
1 2 3 4 5 |
a={p:{x:1}}; b=a.p; deletea.p; |
执行后,b.x依然为1。在销毁对象的时候,要遍历属性中所有后代属性,依次删除。
(6) 自动类型装箱转换
1 2 3 |
vars=”lalalal”; alert(s.length); |
这里s不是对象,js引擎会自动创建一个临时String对象封装s,而这个对象一定会泄漏。
(7) 某些DOM操作
如:IE中,向不在DOM树上的DOM元素appendChild