Credits: This tutorial is written by Volkan. He runs the site Sarmal.com, a bilingual site featuring all his work,products, services,and up-to-date profile information in English and Turkish.
If you are developing client-side re-usable scripting objects, sooner or later you will find yourself spotting out memory leaks. Chances are that your browser will suck memory like a sponge and you will hardly be able to find a reason why your lovely DHTML navigation's responsiveness decreases severely after visiting a couple of pages within your site.
A Microsoft developer Justing Rogers has described IE leak patterns in his excellent article.
In this article, we will review those patterns from a slightly different perspective and support it with diagrams and memory utilization graphs. We will also introduce several subtler leak scenarios. Before we begin, I strongly recommend you to read that article if you have not already read.
Why does the memory leak?
The problem of memory leakage is not just limited to Internet Explorer. Almost any browser (including but not limited to Mozilla, Netscape and Opera) will leak memory if you provide adequate conditions (and it is not that hard to do so, as we will see shortly). But (in my humble opinion, ymmv etc.) Internet Explorer is the king of leakers.
Don't get me wrong. I do not belong to the crowd yelling "Hey IE has memory leaks, checkout this new tool [link-to-tool] and see for yourself". Let us discuss how crappy Internet Explorer is and cover up all the flaws in other browsers".
Each browser has its own strengths and weaknesses. For instance, Mozilla consumes too much of memory at initial boot, it is not good in string and array operations; Opera may crash if you write a ridiculously complex DHTML script which confuses its rendering engine.
Although we will be focusing on the memory leaking situations in Internet Explorer, this discussion is equally applicable to other browsers.
A simple beginning
Let us begin with a simple example:
[Exhibit1-Memoryleakinginsertduetoinlinescript]
<html>
<head>
<scripttype="text/javascript">
functionLeakMemory()...{
varparentDiv=
document.createElement("<divonclick='foo()'>");
parentDiv.bigString=newArray(1000).join(
newArray(2000).join("XXXXX"));
}
</script>
</head>
<body>
<inputtype="button"
value="MemoryLeakingInsert"onclick="LeakMemory()"/>
</body>
</html>
The first assignment parentDiv=document.createElement(...);
will create a div
element and create a temporary scope for it where the scripting object resides. The second assignment parentDiv.bigString=...
attaches a large object to parentDiv
. When LeakMemory()
method is called, a DOM element will be created within the scope of this function, a very large object will be attached to it as a member property and the DOM element will be de-allocated and removed from memory as soon as the function exits, since it is an object created within the local scope of the function.
When you run the example and click the button a few times, your memory graph will probably look like this:
Increasing the frequency
No visible leak huh? What if we do this a few hundred times instead of twenty, or a few thousand times? Will it be the same? The following code calls the assignment over and over again to accomplish this goal:
Exhibit2-Memoryleakinginsert(frequencyincreased)]
<html>
<head>
<scripttype="text/javascript">...
functionLeakMemory()...{
for(i=0;i<5000;i++)...{
varparentDiv=
document.createElement("<divonClick='foo()'>");
}
}
</script>
</head>
<body>
<inputtype="button"
value="MemoryLeakingInsert"onclick="LeakMemory()"/>
</body>
</html>
And here follows the corresponding graph:
The ramp in the memory usage indicates leak in memory. The horizontal line (the last 20 seconds) at the end of the ramp is the memory after refreshing the page and loading another (about:blank) page. This shows that the leak is an actual leak and not a pseudo leak. The memory will not be reclaimed unless the browser window and other dependant windows if any are closed.
Assume you have a dozen pages that have similar leakage graph. After a few hours, you may want to restart your browser (or even your PC) because it just stops responding. The naughty browser is eating up all your resources. However, this is an extreme case because Windows will increase the virtual memory size as soon as your memory consumption reaches a certain level.
This is not a pretty scenario. Your client/boss will not be very happy, if they discover such a situation in the middle of a product showcase/training/demo.
A careful eye may have caught that there is no bigString in the second example. This means that the leak is merely because of the internal scripting object (i.e. the anonymous script onclick='foo()'
). This script was not deallocated properly. This caused memory leak at each iteration. To prove our thesis let us run a slightly different test case:
[Exhibit3-Leaktestwithoutinlinescriptattached]
<html>
<head>
<scripttype="text/javascript">...
functionLeakMemory()...{
for(i=0;i<50000;i++)...{
varparentDiv=
document.createElement("div");
}
}
</script>
</head>
<body>
<inputtype="button"
value="MemoryLeakingInsert"onclick="LeakMemory()"/>
</body>
</html>
And here follows the corresponding memory graph:
As you can see, we have done fifty thousand iterations instead of 5000, and still the memory usage is flat (i.e. no leaks). The slight ramp is due to some other process in my PC.
Let us change our code in a more standard and somewhat unobtrusive manner (not the correct term here, but can't find a better one) without embedded inline scripts and re-test it.
分享到:
相关推荐
此文档描述了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 ...
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
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 ...
本程序是一个在模拟器上定位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 ...
能够辅助您找出应用程序中内存遗失 Memory Leaks 的单元