- 浏览: 1556763 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
nich002:
原网站失效了。撸主简单粗暴的复制过来,可读性极差!差评!
Apache配置详解(最好的APACHE配置教程) -
107x:
不错,谢谢!
LINUX下查看文件夹下的文件个数! -
Hypereo:
好你妹,连个格式都没有!
Apache配置详解(最好的APACHE配置教程) -
resteater:
代码排版感觉有点乱!收发信息代码可读性不强!请问第一次发服务器 ...
java socket例子 -
resteater:
代码排版感觉有点乱!收发信息代码可读性不强!请问第一次发服务器 ...
java socket例子
From:http://www.javascriptkit.com/javatutors/closuresleak/index3.shtml
All of the patterns shown below are described in detail in Justing's article. I'm going through them just for the sake of completeness:
[Exhibit 5 - Circular reference because of expando property] <html> <head> <script type="text/javascript"> var myGlobalObject; function SetupLeak(){ //Here a reference created from the JS World //to the DOM world. myGlobalObject=document.getElementById("LeakedDiv"); //Here DOM refers back to JS World; //hence a circular reference. //The memory will leak if not handled properly. document.getElementById("LeakedDiv").expandoProperty= myGlobalObject; } </script> </head> <body onload="SetupLeak()"> <div id="LeakedDiv"></div> </body> </html>
Here the global variable myGlobalObject
refers to the DOM element LeakDiv
; at the same time LeakDiv
refers to the global object through its expandoProperty
. The situation looks like this:
The above pattern will leak due to the circular reference created between a DOM node and a JS element.
Since the JScript garbage collector is a mark and sweep GC, you may think that it would handle circular references. And in fact it does. However this circular reference is between the DOM and JS worlds. DOM and JS have separate garbage collectors. Therefore they cannot clean up memory in situations like the above.
Another way to create a circular reference is to encapsulate the DOM element as a property of a global object:
[Exhibit 6 - Circular reference using an Encapsulator pattern] <html> <head> <script type="text/javascript"> function Encapsulator(element){ //Assign our memeber this.elementReference = element; // Makea circular reference element.expandoProperty = this; } function SetupLeak() { //This leaks new Encapsulator(document.getElementById("LeakedDiv")); } </script> </head> <body onload="SetupLeak()"> <div id="LeakedDiv"></div> </body> </html>
Here is how it looks like:
However, the most common usage of closures over DOM nodes is event attachment. The following code will leak:
[Exhibit 7 - Adding an event listener as a closure function] <html> <head> <script type="text/javascript"> window.onload=function(){ // obj will be gc'ed as soon as // it goes out of scope therefore no leak. var obj = document.getElementById("element"); // this creates a closure over "element" // and will leak if not handled properly. obj.onclick=function(evt){ ... logic ... }; }; </script> </head> <body> <div id="element"></div> </body> </html>
Here is a diagram describing the closure which creates a circular reference between the DOM world and the JS world.
The above pattern will leak due to closure. Here the closure's global variable obj
is referring to the DOM element. In the mean time, the DOM element holds a reference to the entire closure. This generates a circular reference between the DOM and the JS worlds. That is the cause of leakage.
When we remove closure we see that the leak has gone:
[Exhibit 8- Leak free event registration - No closures were harmed] <html> <head> <script type="text/javascript"> window.onload=function(){ // obj will be gc'ed as soon as // it goes out of scope therefore no leak. var obj = document.getElementById("element"); obj.onclick=element_click; }; //HTML DOM object "element" refers to this function //externally function element_click(evt){ ... logic ... } </script> </head> <body> <div id="element"></div> </body> </html>
Here is the diagram for the above code piece:
This pattern will not leak because as soon as the function window.onload
finishes execution, the JS object obj
will be marked for garbage collection. So there won't be any reference to the DOM node on the JS side.
And the last but not the least leak pattern is the "cross-page leak":
[Exhibit 10 - Cross Page Leak] <html> <head> <script type="text/javascript"> function LeakMemory(){ var hostElement = document.getElementById("hostElement"); // Do it a lot, look at Task Manager for memory response for(i = 0; i < 5000; i++){ var parentDiv = document.createElement("<div onClick='foo()'>"); var childDiv = document.createElement("<div onClick='foo()'>"); // This will leak a temporary object parentDiv.appendChild(childDiv); hostElement.appendChild(parentDiv); hostElement.removeChild(parentDiv); parentDiv.removeChild(childDiv); parentDiv = null; childDiv = null; } hostElement = null; } </script> </head> <body> <input type="button" value="Memory Leaking Insert" onclick="LeakMemory()" /> <div id="hostElement"></div> </body> </html>
Since we observe memory leakage even in Exhibit 1, it is not surprising that this pattern leaks. Here is what happens: When we append childDiv
to parentDiv
, a temporary scope from childDiv
to parentDiv
is created which will leak a temporary script object. Note that document.createElement("<div onClick='foo()'>");
is a non-standard method of event attachment.
Simply using the "best practices" is not enough (as Justing has mentioned in his article as well). One should also adhere to standards as much as possible. If not, he may not have a single clue about what went wrong with the code that was working perfectly a few hours ago (which had just crashed unexpectedly).
Anyway, let us re-order our insertion. The code below will not leak:
[Exhibit 11 - DOM insertion re-ordered - no leaks] <html> <head> <script type="text/javascript"> function LeakMemory(){ var hostElement = document.getElementById("hostElement"); // Do it a lot, look at Task Manager for memory response for(i = 0; i < 5000; i++){ var parentDiv = document.createElement("<div onClick='foo()'>"); var childDiv = document.createElement("<div onClick='foo()'>"); hostElement.appendChild(parentDiv); parentDiv.appendChild(childDiv); parentDiv.removeChild(childDiv); hostElement.removeChild(parentDiv); parentDiv = null; childDiv = null; } hostElement = null; } </script> </head> <body> <input type="button" value="Memory Leaking Insert" onclick="LeakMemory()" /> <div id="hostElement"></div> </body> </html>
We should keep in mind that, although it is the market leader, IE is not the only browser in the world. And writing IE-specific non-standard code is a bad practice of coding. The counter-argument is true as well. I mean, saying "Mozilla is the best browser so I write Mozilla-specific code; I don't care what the heck happens to the rest" is an equally bad attitude. You should enlarge your spectrum as much as possible. As a corollary, you should write standards-compatible code to the highest extent, whenever possible.
Writing, "backwards compatible" code is "out" nowadays. The "in" is writing "forward compatible" (also known as standards compatible) code which will run now and in the future, in current and in future browsers, here and on the moon.
发表评论
-
几个不错的ff下调试插件
2009-12-11 11:14 1817记录一下经常使用的ff插件,其中firebug、switchh ... -
20 种提升网页速度的技巧
2009-04-15 20:19 1199From:http://www.ibm.com/develop ... -
25 个在 Web 中嵌入图表的免费资源
2009-04-14 21:27 1618From: http://www.cnbeta.com/art ... -
15个网站用户体验优化禁忌
2009-04-08 22:57 1129From:http://www.blueidea.com/de ... -
让IE8兼容IE7
2009-03-27 15:10 3937今天在搜狐首页发现:<meta http-equiv ... -
FF下分析页面加载的工具
2009-03-25 16:03 2421今天同事推荐YSlow作为 ... -
IE6下页面显示空白的问题
2009-03-24 17:01 5267今天又碰到了一个页面在IE6下加载完后一片空白的问题,而且页面 ... -
支持IE6、IE7的关闭页面的函数
2009-03-17 15:40 1654function closeWin() { var isI ... -
很弱很无奈的一段代码(打开的页面更新父窗口的链接)
2009-03-12 11:51 990if(parent.window.opener) { pa ... -
js小脚本
2009-02-26 10:13 1496清除元素: var clearNode = functio ... -
处理一次性事件的模式
2009-02-12 20:20 1196有的时候我们需要给一个标签增加一次性的事件,比如先在输入框中增 ... -
Linux:rsync服务器的快速搭建和使用
2008-12-30 10:15 1277From: http://tech.ddvip.com/200 ... -
js导致的页面空白问题
2008-12-29 13:45 3067今天遇到一个很奇怪的问题,系统的一个页面在一台机器上无法完全展 ... -
IE6下history.back无效的问题
2008-12-26 23:56 3747解决IE6中history.back()无法返回的问题:< ... -
浏览器兼容比较好的设置min-width的方式
2008-12-12 18:45 2499<!DOCTYPE HTML PUBLIC " ... -
CSS代码分享:浏览器CSS Reset方法十例zz
2008-12-07 18:06 1113From: http://www.52css.com/arti ... -
在Javascript中,什么是闭包(Closure)
2008-12-02 11:11 1008from: http://javascript.chinaht ... -
Unicode、GB2312、GBK和GB18030中的汉字[转]
2008-11-25 15:22 3803From: http://blog.csdn.net/fmdd ... -
空字符串的split
2008-11-21 19:16 1525本来以为是零,但是在java和js里试了以后发现居然都是1,很 ... -
docType 相关的loose.dtd导致的无法获取scrollTop的解决
2008-11-19 11:32 1629function iecompattest(){ retu ...
相关推荐
此文档描述了Detected memory leaks内存泄漏的简单检测方法,通过调用系统函数,在debug模式下运行,可以很快定位出内存泄漏之处;注:此方法并不能适用所有Detected memory leaks情况
Java memory leaks Java memory leaks Java memory leaks
Finding memory leaks发现内存的泄漏(6KB)
How catch memory leaks with very little effort (7KB)
Finding memory leaks发现内存的泄漏(6KB)
平常我们都会用 Instrument 的 Leaks / Allocations 或其他一些开源库进行内存泄露的排查,但是检查过程非常繁琐,而且不清晰,最主要的是Abandoned memory不会被检测出来。 Leaks 从苹果的开发者文档里可以看到,一...
该资料介绍了如何检测,避免symbian编程中的内存泄漏的方法
一个测试Java内存泄漏的工具,党万春,钱巨,虽然Java语言有自带的垃圾回收机制,Java程序仍然存在由无效引用带来的内存泄漏。而内存泄漏会导致内存耗尽、程序崩溃等严重问题。�
使用__wrap_malloc查找malloc导致内存泄漏问题 memory leak 内存泄漏
本程序是一个在模拟器上定位BREW应用... It can give the call stack of memory leaks (including the locations that MALLOC/REALLOC been called, and also the locations that ISHELL_CreateInstance been called).
You will begin with a basic understanding of memory management, and why memory leaks occur in an application, moving on to autorelease pools and object creation/storage to get an idea of how memory ...
Learn how to analyze CLR 4 .NET application and service crashes and freezes, navigate through memory dump space (managed and unmanaged code) and diagnose corruption, leaks, CPU spikes, blocked ...
Review of General Memory Concepts: Java Heap, Native Memory, and Memory Leaks Investigating Java Heap Out of Memory Errors Review Garbage Collection and Object References Symptoms, Causes, and ...
heading to check memory leaks
本程序是一个在模拟器上定位BREW应用... It can give the call stack of memory leaks (including the locations that MALLOC/REALLOC been called, and also the locations that ISHELL_CreateInstance been called).
用法要从该项目运行特定的codemod,您将运行以下命令: npx ember-memory-leaks-codemod <TRANSFORM> path/of/files/ or/some**/*glob.js# oryarn global add ember-memory-leaks-codemodember-memory-leaks-codemod...
The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption. Use the Memory Analyzer to analyze productive heap dumps with...
The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption. Use the Memory Analyzer to analyze productive heap dumps with ...
BoundsChecker automatically pinpoints static, stack and heap memory errors, and resource leaks. Unlike ordinary memory-checking tools, BoundsChecker validates the latest Windows APIs including ...
Leaks内存泄露检测 最近用到内存泄露,查看以前的博客,方法不错,但操作时,步骤好多都找不到啦,不知道怎么操作。所以下面做了一个简单的例子