Js内存泄露问题总结
最近接受了一个Js职位的面试,问了很多Js的高级特性,才发现长时间使用已知的特性进行开发而忽略了对这门语言循序渐进的理解,包括Java我想也是一样,偶尔在Sun官方看到JDK6.0列举出来的new features才发现很多东西是自己并不知道或者遗忘了的。看来还是要坚持总结技术,反复理解和运用才能保持对任何技术的掌握运用能力阿。
翻了一些Js的新老资料,准备先讲讲Js的内存泄露问题——
当一个DOM对象包含一个Js对象的引用(例如一个Event Handler), 而这个Js对象又持有对这个DOM对象的引用时,一个环状引用就行成了。这本身并不是什么错误或者Bug,因为Js的回收机制能理解这种环状的引用结构并且在没有其他对象能关联到环上的时候回收这个环上的所有对象内存。可不幸的是IE浏览器中的DOM结构并不受Js解释机制管理,所以它并不能理解这种失去外界引用的环状结构,导致环上任何对象都无法被访问到,可是内存依旧占据着,这也就是所谓的Js内存泄露了。
我们来看一个经典的例子说明问题——
- JScript code
(function(limit, delay){
var queue=new Array(10);
var n;
function makeSpan(n){
var s=document.createElement(‘span’);
document.body.appendChild(s);
var t=document.createTextNode(‘ ’+n);
s.appendChild(t);
s.onclick=function(e){
s.style.backgroundColor=’red’;
alert(n);
};
return s;
}
function process(n){
queue.push(makeSpan(n));
var s=queue.shift();
if(s)
s.parentNode.removeChild(s);
}
function loop()}{
if(n<limit){
process(n);
n+=1;
setTimeout(loop,delay);
}
}
loop();
})(10000,10);
这个例子的意义是创建出10000个span元素来添加到DOM的body上,并且对其内容填充序号n,紧接着从queue的第一个位置移除创建的span元素,也就是说10000个为止,不断的创建再移除,永远只保留最新创建的那10个。这个例子满足的条件就是DOM元素带有Js对象即click事件的Event Handler,而Event Handler里面又带有这个DOM元素的引用,于是环状结构行程。
当我在IE上运行这个Js的时候打开任务管理器,很明显的看到此网页的内存从55M左右起很稳定的增长直到结束第10000个span创建完毕停止增长时已经到了167M,而在Firefox上运行此Js得到的数据是从头到尾内存都不会超过70M。这已经说明IE一直都没有解决这种Js内存泄露的问题,即使我用的版本已经是最新的IE8.0。
可以想象在如今Ajax运用越来越多,用户体验要求越来越高的情况下,网页的体积会越来越庞大,可能很频繁的Js程序员需要做的事情就是在某个DOM元素例如Div里添加很多Html代码,用innerHTML赋值进去,然后用户触发某事件后又整个替换掉innerHTML,那么被替换以前的Html代码很可能带有这样的环状结构,导致页面只要不刷新,内存就会一直泄露着越来越严重,直到吃光机器内存。
所以我们提倡人为的打破这种环状结构, 即在DOM元素被抛弃之前移除绑定在上面的Js Event Handler,移除的方法就涉及到DOM事件模型的讨论范围了,我已在另外一篇讨论文章中详细机讲解W3C标准的DOM事件模型和IE的到底有什么区别了,有兴趣的可以看一看。
当然浏览器厂商特别是IE也希望能负起一定的责任起来,早日大一统,算是为广大Js程序员造福吧!
Js内存泄露问题总结的更多相关文章
- JS内存泄露常见原因
详细内容请点击 分享的笔记本-前端 开发中,我们常遇见的一些关于js内存泄露的问题,有时候我们常常会找半天找不出原因,这里给大家介绍简单便捷的方法 1.闭包上下文绑定后没有释放: 2.观察者模式在 ...
- js内存泄露的几种情况详细探讨
内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.在C++中,因为是手动管理内存,内存泄露是经常出现的事情.而现在流行的C#和Java等语言采用了自动垃圾回收方法管理内存,正常使 ...
- js内存泄露的几种情况
想解决内存泄露问题,必须知道什么是内存泄露,什么情况下出现内存泄露,才能在遇到问题时,逐个排除.这里只讨论那些不经意间的内存泄露. 一.什么是内存泄露 内存泄露是指一块被分配的内存既不能使用,又不能回 ...
- javascript js 内存泄露
JavaScript 内存泄露 1.什么是闭包.以及闭包所涉及的作用域链这里就不说了. 2.JavaScript垃圾回收机制 JavaScript不需要手动地释放内存,它使用一种自动垃圾回收机制(ga ...
- 一个JS内存泄露实例分析
在看JS GC 相关的文章时,好几次看到了下面这个设计出来的例子,比较巧妙,环环相扣. var theThing = null; var replaceThing = function () { ...
- 浅谈 JS 内存泄露方式与避免方法(二)
Concept WHAT : 内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.正常情况下,垃圾回收器在DOM元素和event处理器不被引用或访问的时候回收它们.但是,IE的早些 ...
- Node.js 内存泄露 定位
之前我们在64位Linux服务器上使用Node.js时,当Node进程物理内存接近1.6G,由于谷歌V8引擎对内存的限制,会导致进程退出! 显然我们自身编码或npm加载的第3行模块存在内存泄露问题,那 ...
- node.js内存泄露问题记录
先说一下.事情的来龙去脉. 公司开发一款游戏棋牌游戏,服务端的开发是IO密集型,开发的时候,考虑过使用python,java,node.js. 终于选择了node.js(node.js宣传的杀手功能. ...
- javascript js 内存泄露工具使用
javascript内存泄露工具使用 原文:http://lanhy2000.blog.163.com/blog/static/43678608201121472644851/ 2011-03-14 ...
随机推荐
- C++对C语言的非面向对象特性扩充(1)
我将分3篇来介绍C++相对于C在非对象特性上的扩充,今天要讲的是C++在注释,输入输出,局部变量说明的扩充,以及const修饰符与C中的#define的比较. 1.C++注释除了包括原有C的块注释/* ...
- 杭电oj An easy problem
</pre><h1 style="color: rgb(26, 92, 200);">An easy problem</h1><stron ...
- Non recursive Depth first search
深度优先非递归实现算法: 1 递归算法: //初始化相关数据结构 DFS(G) ------------------------------------------------------------ ...
- USB接口定义
一般的排列方式是:红白绿黑从左到右 定义: 红色-USB电源 标有-VCC.Power.5V.5VSB字样 绿色-USB数据线(正)-DATA+.USBD+.PD+.USBDT+ 白色-USB数据线( ...
- 1354 - IP Checking(水题)
1354 - IP Checking PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB An I ...
- FFmpeg源码结构图 - 解码
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
- N皇后( DFS,推荐)
N皇后问题 Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任 ...
- c++ ,protected 和 private修饰的构造函数
c++ protected 和 private修饰的构造函数: 1.在类的外部创建对象时,不能调用protected或private修饰的构造函数. 2.当子类中的构造函数调用父类的private构造 ...
- HDU 3068 最长回文 【最长回文子串】
和上一题一样,不过这题只是要求最长回文子串的长度 在此采用了非常好用的Manacher算法 据说还是O(n) 的效率QAQ 详细用法参考了上篇博客的参考资料,这两天有空学习一下~ Source cod ...
- 转: Firefox 浏览器对 TABLE 中绝对定位元素包含块的判定有错误
标准参考 元素的包含块 W3C CSS2.1 规范中规定,绝对定位元素的包含块(containing block),由离它最近的 position 特性值是 "absolute". ...