Logo

never-online

A crisis is a terrible thing to waste.
  • Blog首页
  • 推荐日志
  • 关于我
  • 留言簿
  • 设计
  • 订阅RSS
  • 登录
« innerHTML在Mozilla ...
在Javascript中,什... »
分类: Web Dev
推荐日志

GC机制以及IE Jscript内存泄露探究,(不定期更新。)

[ 2006-09-16 02:03:49 | 作者: never-online ]
字体大小: 大 | 中 | 小
Close Advertisement
特别注明:本文章只对于Microsoft Jscript所写的文章,此文的一些资料来源于网上,将在文章最后给出参考来源。文中若有错误,或字词用得不恰当的地方,请指出。以免误了以后看这篇文章的人。
这篇文章估计要写一些时间,因为我即然写了GC机制探究,我就想用C++的语言来自己模拟下这个mark-sweep算法。也许不会在本文出现,但至少对于理解如何写好Jscript和Script或者说理解GC来说,是很有好处的。

关键词:GC(Garbage Collector), closure, memory leak

文章思路——了解IE的GC回收机制,结合MS的一些对其Memory Leak的解释,针对代码作相应的注释,这样对IE下的memory leak心里就自然有一把秤了。

1。GC(垃圾回收器)
在IE6.0中,对于javascript object内部,jscript使用的是nongeneration mark-and-sweep算法,而对于javascript object与外部object(包括native object和vbscript object等等)的引用时,IE 6使用的才是计数器的算法,引用计数法(Reference Counting Collector) ,下面是对于GC的两种处理方法的一些资料和一些自己的理解:

  引用计数法是唯一没有使用根集的垃圾回收得法,该算法使用引用计数器来区分存活对象和不再使用的对象。一般来说,堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给任意变量时,引用计数器每次加1。当对象出了作用域后(该对象丢弃不再使用),引用计数器减1,一旦引用计数器为0,对象就满足了垃圾收集的条件。

  基于引用计数器的垃圾收集器运行较快,不会长时间中断程序执行,适宜地必须 实时运行的程序。但引用计数器增加了程序执行的开销,因为每次对象赋给新的变量 ,计数器加1,而每次现有对象出了作用域生,计数器减1。

tracing算法(Tracing Collector)

  tracing算法是为了解决引用计数法的问题而提出,它使用了根集的概念。基于tracing算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪些对象不可达,并用某种方式标记可达对象,例如对每个可达对象设置一个或多个位。在扫描识别过程中,基于tracing算法的垃圾收集也称为标记和清除(mark-and-sweep)垃圾收集器。用程序的来表达可以这样:
Copy Code(拷贝代码)-Run HTML(运行代码)-Save Code(另存代码)
for each root variable r
 mark (r);
sweep ();

void mark (Object p)

 if (!p.marked)

 p.marked = true;
 for each Object q referenced by p
 mark (q);

void sweep ()

 for each Object p in the heap

 if (p.marked)
 p.marked = false
 else
 heap.release (p);
执行过程如图:

uploads/200609/16_024442_mark_sweep.gif


2。对于IE下的几种内存泄露

1),最常见的就是Circular References(循环引用),看这张图:
uploads/200609/16_012616_ie_leak_patterns_fig01.gif

举一个明显的例子。
Copy Code(拷贝代码)-Run HTML(运行代码)-Save Code(另存代码)
<html>
 <head>
 <script language="JScript">

 var myGlobalObject;

 function SetupLeak()
 {
 // First set up the script scope to element reference
 myGlobalObject =
 document.getElementById("LeakedDiv");

 // Next set up the element to script scope reference
 document.getElementById("LeakedDiv").expandoProperty =
 myGlobalObject;
 }

 function BreakLeak()
 {
 document.getElementById("LeakedDiv").expandoProperty =
 null;
 }
 </script>
 </head>

 <body onload="SetupLeak()" onunload="BreakLeak()">
 <div id="LeakedDiv"></div>
 </body>
</html>

如果一会儿还不能理解代码,请看下面的示意图:
uploads/200609/16_012502_memory_leak_1.png


那随之而来一个问题,为什么这样会有Memory Leak?

在这里有一篇文章可以探究http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx。
The benefits of this approach are numerous, but the principle benefit is that circular references are not leaked unless the circular reference involves an object not owned by JScript.

"采用此方法带来很多好处,其根本的益处在于处于循环引用不会被释放,直到Jscript的Object不在属于此循环引用当中。"
其根本原因也是由于IE使用的是GC回收机制的问题。在上文已经给出了nongeneration mark-and-sweep算法示意图。
IE中可以正常的处理Script级的纯Object之间循环引用,也就是这样
Copy Code(拷贝代码)-Run HTML(运行代码)-Save Code(另存代码)
<script>
var objA = new Object; objA.a = "never-online";

var objB = new Object; objB.ref = objA;

var objRef = new Object;

objRef = objB.ref;
alert(objRef.a);

delete objRef;
delete objB;
delete objA;
</script>

而不能正确的处理,Object与DOM之间交互的循环引用。如第一个例中所展示的那样出现Memory Leak。

这样应该很好理解了。再举一个例子。

//TODO

Javascript的垃圾回收机制
在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。
文章继续编写中...
[最后修改由 Rank, 于 2008-04-15 15:35:21]
评论Feed 评论Feed: http://www.never-online.net/blog/feed.asp?q=comment&id=105

浏览模式: 显示全部 | 评论: 2 | 引用: 0 | 排序 | 浏览: 4979
引用 xLight*
[ 2006-09-15 19:26:15 ]
顶你个文章编写中

我用手机上网容易吗,打开就看到个文章编写中。

QWERT键盘让我输入不在是瓶颈。:)

等你下文啦
引用 never-online
[ 2006-09-15 22:18:12 ]
:D,今天晚上应该就可以出稿了。

发表
表情图标
[smile] [confused] [cool] [cry]
[eek] [angry] [wink] [sweat]
[lol] [stun] [razz] [redface]
[rolleyes] [sad] [yes] [no]
[heart] [star] [music] [idea]
UBB代码
转换链接
表情图标
悄悄话
昵        称:  3-24字符, 不可使用特殊字符 *
安全规则: 请输入规则答案: 2+5=? *
 
Language Package
  • ENGLISH
  • 简体中文
用户面板
用户名:
密码:
安全规则: 2+5=?
注册
分类
  • Blog首页
  • Android [2] Android RSS Feed
  • Diary & Misc [115] Diary & Misc RSS Feed
  • Web Dev [112] Web Dev RSS Feed
  • Never Modules(JS) [12] Never Modules(JS) RSS Feed
  • Flash & Flex & Air [4] Flash & Flex & Air RSS Feed
  • PHP & Apache [1] PHP & Apache RSS Feed
  • XML [7] XML RSS Feed
  • CSS [7] CSS RSS Feed
  • ASP & .NET [3] ASP & .NET RSS Feed
  • Literature Archives [4] Literature Archives RSS Feed
  • Design [17] Design RSS Feed
  • Visual Basic [3] Visual Basic RSS Feed
最新评论
  • [cry] 非常感谢,这是我...
  • 很精彩,学习了:) [smi...
  • 很精彩
  • 好文,收藏至20ju.com
  • 好文,收藏至20ju.com
  • 弹出的匹配框不能随着页...
  • @lily 多年前的东西了,...
  • 为什么在chrome中不支持...
  • @gzman 那阵子确实想蛮多...
  • 兄弟,想太多了吧
  • [smile] [wink] [sweat] ...
  • javascript:insertSmilie...
  • 我新建了两个sliderbar都...
  • 不错哦````````
  • 好文,收藏至20ju.com
搜索

统计数据
日志: 287
评论: 853
引用: 0
用户: 117
到访: 4144578
在线: 1

新浪微博
Links
  • 阿肆
  • 好奇
  • 小龙人
  • 小萌
  • Zerray
  • realdodo
  • ps album
  • my flickr
  • XiaoFeng
  • 神~ORZ
  • Jiuan's blog
  • yanpeng's blog
  • zhoux's blog
  • winter
  • aoao
  • jerry.qu
  • JoelLeung
  • monyer
  • Miller
  • PuterJam
  • Terry
  • JK
  • akira
  • dh20156's New World!
  • Joshua
  • Estyle
  • 互联网人
  • 兔子
  • 电脑爱好者
  • 阿笨狗
Favorite
  • leica china
  • Douglas Crockford
  • dhteumeuleu
  • regexplib
  • webfx
  • ajaxian
  • John Resig
  • dean
  • Adam McCrea
  • css beauty
  • livepipe
  • smashing magazine
  • ericlippert
  • narcissus
  • PPK
widget

Powered by LBS Version 2.0.304 © 2003-2005 SiC/CYAN. - Template writen by never-online - 桂ICP备07010684号
17 DB Queries | Proccessed in 110ms