`
bcyy
  • 浏览: 1881069 次
文章分类
社区版块
存档分类
最新评论

JavaScript and memory leaks

 
阅读更多

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.

分享到:
评论

相关推荐

    sgcWebSockets 4.1.0.Full.Source稳定版

    负载平衡,MQTT协议支持,修正大量Bug,最新稳定版 Delphi7/XE6/XE7/XE8 *******************************************... [*] : Fixed Memory Leaks on NextGen compiler. [*] : Fixed WebRTC Chrome console errors.

    memwatch_for_memory_leak_detect

    const arr = new Array(10000).fill(new Array(10000).fill('memory leak')); } ``` 在这个例子中,我们首先监听 `leak` 事件,当检测到内存泄漏时,会输出相关信息。然后定义了一个 `reportSnapshot` 函数,用于...

    内存泄漏检测工具

    除了“IE Javascript leaks detector”,还有其他内存泄漏检测工具,例如`Drip-0.2.exe`(Drip Memory Leak Detector),这是一款适用于Node.js环境的内存泄漏检测工具。它能够帮助开发者监测Node.js应用程序的内存...

    谷歌地图 delphi 封装库 2013 0.1.9 全面支持google maps api

    - bug fixed: some memory leaks fixed (there is still some) (thanks Donovan) - Improvement: TGMCircle -&gt; modified all Set and ShowElements methods to use the new method ChangeProperties inherited ...

    sgcWebSockets_source_4.1.0

    ******************************************************* sgcWebSockets **************************************... [*] : Fixed Memory Leaks on NextGen compiler. [*] : Fixed WebRTC Chrome console errors.

    jdk1.7_80 window.64

    It provides just-in-time (JIT) compilation for faster runtime performance and includes garbage collection mechanisms for efficient memory management. 2. **Java Language Enhancements:** - The ...

    简单三步,搞掂内存泄漏

    原文地址:http://www.jackslocum.com/blog/2006/10/02/3-easy-steps-to-avoid-javascript-memory-leaks/ 你可能还未知道,你浏览的大多数的js网站,会引起 内存泄漏。听起来有点夸张,但这是事实,难道我会骗你吗?...

    React-内存泄露常见问题解决方案.docx

    不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。 JavaScript 中常见的几种内存泄露 ----------------------------- ### 全局变量引起的内存泄露 在 JavaScript 中,变量的作用域是函数范围的。...

    Iframe内存泄露分析

    检测内存泄漏的工具和手段确实有限,仅有的两个工具(JavaScript Memory LeakDetector 和 sIEve )都不太好用,不像 Java 里面的一些工具能精准定位。因此,需要通过经验预测最有可能泄漏的几个点,再通过排除法,...

    scrapy官方手册

    **4.8 Debugging memory leaks(调试内存泄漏)** 在长时间运行的爬虫中可能会遇到内存泄漏的问题,这部分内容介绍了如何定位和解决这类问题。 **4.9 Downloading and processing files and images(下载和处理...

    php.ini-development

    and you cannot use both "ob_gzhandler" and "zlib.output_compression". ; Note: output_handler must be empty if this is set 'On' !!!! ; Instead you must use zlib.output_handler. ; ...

Global site tag (gtag.js) - Google Analytics