sitelink1  
sitelink2  
sitelink3  
sitelink4 http://1 
extra_vars4 ko 
extra_vars5 http://www.javascriptkit.com/javatutors/closuresleak/index.shtml 
extra_vars6 sitelink1 

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:

[Exhibit 1 - Memory leaking insert due to inline script]
·미리보기 | 소스복사·
  1. <html>   
  2. <head>   
  3. <script type="text/javascript">   
  4.     function LeakMemory(){   
  5.         var parentDiv =    
  6.              document.createElement("<div onclick='foo()'>");   
  7.   
  8.         parentDiv.bigString = new Array(1000).join(   
  9.                               new Array(2000).join("XXXXX"));   
  10.     }   
  11. </script>   
  12. </head>   
  13. <body>   
  14. <input type="button"    
  15.        value="Memory Leaking Insert" onclick="LeakMemory()" />   
  16. </body>   
  17. </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:

[Exhibit 2 - Memory leaking insert (frequency increased) ]
·미리보기 | 소스복사·
  1. <html>   
  2. <head>   
  3. <script type="text/javascript">   
  4.     function LeakMemory(){   
  5.         for(i = 0; i < 5000; i++){   
  6.             var parentDiv =    
  7.                document.createElement("<div onClick='foo()'>");   
  8.         }   
  9.     }   
  10. </script>   
  11. </head>   
  12. <body>   
  13. <input type="button"    
  14.        value="Memory Leaking Insert" onclick="LeakMemory()" />   
  15. </body>   
  16. </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:

[Exhibit 3 - Leak test without inline script attached]
·미리보기 | 소스복사·
  1. <html>   
  2. <head>   
  3. <script type="text/javascript">   
  4.     function LeakMemory(){   
  5.         for(i = 0; i < 50000; i++){   
  6.             var parentDiv =    
  7.             document.createElement("div");   
  8.         }   
  9.     }   
  10. </script>   
  11. </head>   
  12. <body>   
  13. <input type="button"    
  14.        value="Memory Leaking Insert" onclick="LeakMemory()" />   
  15. </body>   
  16. </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.

번호 제목 글쓴이 날짜 조회 수
157 setTimeout() / setInterval() 메소드 황제낙엽 2008.11.05 111
156 IE브라우저에서 서버의 XML파일을 ajax로 가져와 DOM파싱하는 예제 (XMLHttpRequest, XML, ActiveXObject) 황제낙엽 2018.11.23 103
» [JavaScript Tutorials] JavaScript and memory leaks (해석중) 황제낙엽 2009.04.08 102
154 자바스크립트 정렬(javascript formatter) 도구 JavaScript Code Improver file 황제낙엽 2011.04.04 97
153 javascript replaceall의 방법에 따른 처리 속도 비교 황제낙엽 2009.02.11 97
152 int * float 연산 오류 file 황제낙엽 2008.12.11 95
151 JavaScript Reserved Words 황제낙엽 2011.11.28 94
150 DOM과 innerHTML 방법에 대한 비교 분석 황제낙엽 2008.11.03 94
149 자바 스크립트 플러그인 황제낙엽 2005.11.22 94
148 Ajax (XMLHttpRequest) 샘플 황제낙엽 2017.08.01 93
147 innerHTML 황제낙엽 2008.11.03 93
146 [펌] 아사페릴의 사생활 - 싱글톤 패턴을 지향한 Javascript Module Pattern 황제낙엽 2009.04.02 90
145 크로스 브라우저를 위한 브라우저 검사 코드 file 황제낙엽 2010.08.27 86
144 자바스크립트 타입 비교 테이블 + 테이블 작성 스크립트 [1] file 황제낙엽 2017.06.23 85
143 [JavaScript Tutorials] Error handling in JavaScript using try/catch/finally - The Error object and throwing your own errors (해석중) 황제낙엽 2009.04.10 82
142 Alert 에서의 개행처리 황제낙엽 2012.03.09 80
141 JSAPI User Guide 황제낙엽 2008.07.14 79
140 JSON.parse() - feat. Object.assign 황제낙엽 2017.07.09 77
139 Understanding User-Agent Strings 황제낙엽 2011.02.22 76
138 이클립스에 Aptana 플러그인 설치하기 (자바스크립트 개발에 유용한 IDE) 황제낙엽 2009.04.17 75