最近接受了一个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. md5 加密 swfit版

    在swift工程中随便建一个objective-c类,会提示你生成一个Bridging-Header,点YES,然后删除刚才建立的objective-c类,只留下[工程名]-Bridging-Head ...

  2. spring的常用配置

    bean.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http ...

  3. POJ 2250 Compromise(LCS)

    POJ 2250 Compromise(LCS)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87125#proble ...

  4. 关于Ubuntu远程ssh连接失败的问题

    在做机器人项目的时候,用的是Ubuntu的linux,跟之前的CentOS的操作命令有一点差别,就比如防火墙的名字,在Ubuntu系统中叫什么ufw,真是有点不好接受. 为了能模拟环境,我又弄了一台电 ...

  5. Django forms 关于select和checkbox设置初始选中值及让前端选中指定值

    Django的forms和models一样很牛逼.他有两种功能,一是生成form表单,还有就是form表单的验证. 这里主要说一下生成form表单时经常用到的需要设置 初始值 / 默认值 的情况. 1 ...

  6. [LeetCode]题解(python):044-Wildcard Matching

    题目来源: https://leetcode.com/problems/wildcard-matching/ 题意分析: 定义两个新字符规则,'?'代表任意一个字符,’*‘代表任意长度的任意字符.输入 ...

  7. 深入浅出—JAVA(6)

    6.认识JAVA的API Arraylist的操作

  8. 转:你真的懂得JS吗?

    题目1 if (!("a" in window)) { var a = 1; } alert(a); // undefined, ~~~所有全局变量都是window的属性,声明语句 ...

  9. 如何配置和使用Tomcat访问日志

    配置位置在log下的server.xml,(tomcat容器) <Engine defaultHost="localhost" name="Catalina&quo ...

  10. A. Liserious战队

    Liserious战队是一支活跃在京沪地区的著名密室逃脱战队,在优秀的队长Liserious和芳姐的带领下,打遍天下大大小小的密室逃脱,攻无不克,战无不胜,上天入地无所不能. 世界密室逃脱委员会以IS ...