Using XPCOM in JavaScript withoutleaking(about FF)

来源:互联网 发布:广东高职高考网络视频 编辑:程序博客网 时间:2024/05/16 08:23

======================================================
注:本文源代码点此下载
======================================================

本文适合有一定javascript基础读者阅读。

javascript内存泄露的相关问题已经是老生常谈了,但是也常常不被大家所重视,事实是一般下它对于用户体验没有多大的影响。但作为一枚苦逼奋斗的fe,这种问题绝对要尽量避免,以此文章和大家探讨一下关于javascript的内存泄露。

我们都知道javascript是一种垃圾收集语言,他的内存是根据对象的创建分配内存给对象的,在没有引用的情况下浏览器会把其分配的内存收回。但是由于ie对javascript对象和com对象使用不同的垃圾收集例程(ps:ff的mozilla's xpcom也是),他们使用的是引用计数的模式(传说中的罪魁祸首)。

这里必须拓展一下:javascript中最常用的垃圾收集方式是标记清除。当变量进入环境的时候,就给他贴上一个“已入狱进入环境”的标记。咳咳,事实上这个环境就像一个监狱,因为只要执行流进入了相应的环境,他们就会被使用。而变量离开的时候,他们的标记是”保释出狱离开环境“。垃圾收集器是个醒目的娃儿,他会在运行的时候给存储在内存中的所有变量加上标记。然后把环境中的变量那个以及环境中变量引用的变量(很绕口)他们的标记都去掉。然后还有标记的变量们,他们就会被删除(枪毙),因为环境中的变量已经无法访问到他们了(说!你是不是从gfw来的)。最后,垃圾收集器完成了内存清楚的工作,销毁他们的内存空间(总算是折腾完了)。

以上就是现在最常用的垃圾收集方式:标记清除。下面我们继续说万恶的引用计数,咳咳。其实引用计数木有什么不好,但是遇到了内存引用,他的名字就不好听了。当两个对象互相引用的时候,便构成了循环引用,其中每个对象都赋一个引用计数值1,这样的话两个引用计数就永远不会是零了,于是乎对象被判了无期徒刑,飘零在内存空间里面。

栗子 1 :

function leak(){

var obja = new object();

var objb = new object();

obja.value = objb;

objb.value = obja;

}

如上所示,一场对象之间充满基情的循环引用产生了。

栗子2:

html>

body>

script type="text/javscript">

function leak(){

var element= document.getelementbyid('elementa');

element.onclick = function(){

alert(element.id);

}

}

script>

div id="elementa">div>

body>

html>

上面的部分我们获取了一个id叫做elementa的div,然后我们创建了一个元素事件处理程序的闭包。这个闭包充满基情的包含了一个element.id,咳咳。这个闭包不肯放走element包含的dom对象。这是为什么 ?让我们深究一下吧因为匿名函数保存了一个对于leak()的函数的活动对象的引用,因此会导致无法减少element的引用数。只要匿名函数一天在,他他就会包庇着element,给他假户口让他的引用数不少于1,所以在引用计数的制度下垃圾收集策略下,因此他就会永久占有经济适用房内存空间。

但大侦探们前端开发人员们总是无所不能的,我们做出了小小的添加,一切都不一样了——

html>

body>

script type="text/javscript">

function leak(){

var element= document.getelementbyid('elementa');

var id = element.id;

element.onclick = function(){

alert(id);

}

element= null;

}

script>

div id="elementa">div>

body>

html>

咳咳,各位水客应该对上面的技巧毫不陌生。上述的部分,我们把element.id保存在了另外一个变量上面,接着闭包引用了变量之后消除循环引用。觉得这样就斩草除根了吗?nonono,切记了,闭包会引用包含函数的整个活动对象,也就是说,引用了变量id,还会顺手牵出了element。即使没有直接引用,也要在最后吧element设置为null。这样就能解除对dom对象的引用,完成内存的顺利回收。

关于内存泄露,有很多大牛们都发表了不同的意见。如果看了我的赶脚看得不够,还有以下任意门:

http://www.codeproject.com/kb/scripting/leakpatterns.aspx

memory leakage in internet explorer(about ie)

https://developer.mozilla.org/en/using_xpcom_in_javascript_without_leaking

using xpcom in javascript withoutleaking(about ff)


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
原创粉丝点击