最近接受了一个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内存泄露问题总结的更多相关文章

  1. JS内存泄露常见原因

    详细内容请点击 分享的笔记本-前端 开发中,我们常遇见的一些关于js内存泄露的问题,有时候我们常常会找半天找不出原因,这里给大家介绍简单便捷的方法 1.闭包上下文绑定后没有释放:   2.观察者模式在 ...

  2. js内存泄露的几种情况详细探讨

    内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.在C++中,因为是手动管理内存,内存泄露是经常出现的事情.而现在流行的C#和Java等语言采用了自动垃圾回收方法管理内存,正常使 ...

  3. js内存泄露的几种情况

    想解决内存泄露问题,必须知道什么是内存泄露,什么情况下出现内存泄露,才能在遇到问题时,逐个排除.这里只讨论那些不经意间的内存泄露. 一.什么是内存泄露 内存泄露是指一块被分配的内存既不能使用,又不能回 ...

  4. javascript js 内存泄露

    JavaScript 内存泄露 1.什么是闭包.以及闭包所涉及的作用域链这里就不说了. 2.JavaScript垃圾回收机制 JavaScript不需要手动地释放内存,它使用一种自动垃圾回收机制(ga ...

  5. 一个JS内存泄露实例分析

    在看JS GC 相关的文章时,好几次看到了下面这个设计出来的例子,比较巧妙,环环相扣.   var theThing = null; var replaceThing = function () { ...

  6. 浅谈 JS 内存泄露方式与避免方法(二)

    Concept WHAT : 内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束.正常情况下,垃圾回收器在DOM元素和event处理器不被引用或访问的时候回收它们.但是,IE的早些 ...

  7. Node.js 内存泄露 定位

    之前我们在64位Linux服务器上使用Node.js时,当Node进程物理内存接近1.6G,由于谷歌V8引擎对内存的限制,会导致进程退出! 显然我们自身编码或npm加载的第3行模块存在内存泄露问题,那 ...

  8. node.js内存泄露问题记录

    先说一下.事情的来龙去脉. 公司开发一款游戏棋牌游戏,服务端的开发是IO密集型,开发的时候,考虑过使用python,java,node.js. 终于选择了node.js(node.js宣传的杀手功能. ...

  9. javascript js 内存泄露工具使用

    javascript内存泄露工具使用 原文:http://lanhy2000.blog.163.com/blog/static/43678608201121472644851/ 2011-03-14 ...

随机推荐

  1. BZOJ 1620: [Usaco2008 Nov]Time Management 时间管理( 二分答案 )

    二分一下答案就好了... --------------------------------------------------------------------------------------- ...

  2. PHP自练项目中个人中心创建,修改,验证(服务器端和客户端验证)

    当注册成功到登录后进入个人中心,查看和修改自己的资料 第一步:创建个人中心: <?php //定义个常量,用来授权调用includes里面的文件 define('IN_TG',true); // ...

  3. Python:爬取乌云厂商列表,使用BeautifulSoup解析

    在SSS论坛看到有人写的Python爬取乌云厂商,想练一下手,就照着重新写了一遍 原帖:http://bbs.sssie.com/thread-965-1-1.html #coding:utf- im ...

  4. 405 HTTP method GET is not supported by this URL

    孙鑫java web开发详解P285里面提交Get网站弹出提示405 HTTP method GET is not supported by this URL 原因父类doGet()方法未覆盖. 应写 ...

  5. bootstrap基础知识

    Bootstrap是Twitter推出的一款简洁.直观.强悍的前端开发框架. Bootstrap基于 HTML.CSS.JAVASCRIPT.它由Twitter的设计师Mark Otto和Jacob ...

  6. qt 操作word

    //修改doc QString filepath="e:\\aa.doc"; QAxWidget *word = new QAxWidget("Word.Applicat ...

  7. perl 处理json 数组格式

    [root@dr-mysql01 ~]# cat a1.pl use Encode; use JSON; use URI::Escape; use LWP::Simple; my $host = &q ...

  8. Hadoop Hive sql语法详解

    Hadoop Hive sql语法详解 Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件 ...

  9. 将string当字节流使

    string是C++标准定义的字符串类,它不但支持文本,而且支持二进制字节流.给一个string变量赋值有多种方法: 1) 拷贝构造函数 2) 等号赋值函数 3) append成员函数 4) push ...

  10. Card Game Cheater(贪心+二分匹配)

    Card Game Cheater Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...