민서네집

IE9 이하에서 (IE9 포함) Memory Leak 이 발생하는 경우 본문

WEB (HTML, CSS)

IE9 이하에서 (IE9 포함) Memory Leak 이 발생하는 경우

브라이언7 2013. 12. 17. 21:16

IE memory profilers for Javascript [duplicate]


http://stackoverflow.com/questions/13475937/ie-memory-profilers-for-javascript


Tools for Detecting Memory Leaks


JavaScript Profiler in IE


http://stackoverflow.com/questions/20376/javascript-profiler-in-ie


IE memory profilers for Javascript [duplicate]


Memory Leakage in Internet Explorer - revisited



Understanding and Solving Internet Explorer Leak Patterns


IE Memory Leak – jQuery Fix


http://kossovsky.net/index.php/2009/07/ie-memory-leak-jquery-garbage-collector/


댓글에 보니 jQuery 를 수정해서 문제를 해결했다는 얘기도 있긴 했지만, 내가 해 봤을 때는 별 효과가 없었다.


IE memory leak


http://epro.tistory.com/6


1. 원인은?

Understanding and Solving Internet Explorer Leak Patterns를 참고해 보면 순환참조 부분이 가장 의심이 되었다.
Ajax를 편하게 쓰기 위해 XMLHttpRequest를 생성해주는 function을 만들어 두고 필요할때 불러서 쓰곤 했는데, 이 부분에서 문제가 있는 듯 했다.
local variable은 function이 종결되면 가비지컬렉터에 의해 삭제되어야 하는데, parameter로 다른 function에 참조되어 있을 경우- 이런 경우를 순환참조라고 하는 것 같다 - 는 leak의 원인이 된다고 한다. (어설픈 해석이다. 대충 이런 뜻인 것 같다)

.... It isn't immediately obvious that parent function parameters and local variables will be frozen in time, referenced, and held until the closure itself is released. .... Because we've added a closure, a second reference is made, and that second reference won't be released until the closure is also released. .....

정확한 내용은 Reference의 Closures부분을 참조할 것
그래서 지역변수로 선언된 XMLHttpRequest를 전역변수로 빼고 비교해 보기로 했다.


Screencast: Diagnosing JavaScript Memory Leaks in IE


http://www.barelyfitz.com/screencast/javascript/memory-leak/


[스크립트] Script 메모리 누수에 대한 TIP


http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=71441


JavaScript and memory leaks


Memory leaks

http://javascript.info/tutorial/memory-leaks


Understanding and Solving Internet Explorer Leak Patterns

http://msdn.microsoft.com/en-us/library/ms976398.aspx


IE9 이하에서 (IE9 포함) Memory Leak 이 발생하는 경우 -


[2013-12-24]

5초마다 한번씩 반복적으로 ajax로 호출을 하니까 chrome 브라우저에서는 괜찮은데, IE 8, 9 에서는 메모리 증가 현상이 뚜렷했다. 저녁에 웹페이지를 켜 놓은 상태에서 퇴근하고, 아침에 출근해 보면 IE가 먹통이 되었다.

나는 처음에는 ajax 의 반복 호출로 인해 메모리가 조금씩 쌓였을 것이라고 생각했는데, ajax 에서 아무 일도 안 한 상태로 반복 호출해보니 메모리 증가 현상이 없었다. 


ajax 로 서버에서 리스트를 받아서 웹페이지에서 table 태그를 지우고, 다시 써 넣는 작업을 하고 있다.


원인은 <a> 태그 안에 onclick='...' 으로 문자열로 넣은 부분 때문이었다.

IE 9 버전 이하에서는 웹브라우저의 Garbage Collector 의 버그 때문에 이런 경우 onclick 안의 function 의 참조 때문에 화면에서 지워진 태그가 Garbage Collect 되지 않는 것 같다.


Chrome Browser 와 IE 11 브라우저에서는 메모리 증가 현상이 없었다.


해결책은 다음 코드와 같이 onclick='...' 으로 문자열을 적어 넣지 말고, jquery의 bind() 메서드를 사용하면 된다.


// [2013-12-24] Heeseok
// 다음과 같이 하면 IE 9 이하에서 Memory Leak 이 발생하므로 bind 메서드를 써준다.
//td.html("<a href='javascript:" + fnGoDetail + "()' onclick='" + fnGoDetail + "(this);return false;'>" + list[r][col] + "</a>");
td.html("<a href='javascript:" + fnGoDetail + "()'>" + list[r][col] + "</a>");
td.find('a').bind("click", function() {
	eval(fnGoDetail + "(this)");
	return false;
});


IE Process의 Memory 를 30초 단위로 파일로 저장하는 배치 파일


@echo off

SET count=0

SET mem=tasklist /fi ^"imagename eq iexplore.exe^" /NH

echo --------------------------------------------------------------------------- >> memory_iexplore.log

:start

SET /A count+=1

echo %date% %time% (%count%) >> memory_iexplore.log

%mem% >> memory_iexplore.log

echo --------------------------------------------------------------------------- >> memory_iexplore.log

TIMEOUT 30

goto start


배치 파일명: memory_iexplore.cmd
저장하는 로그 파일명: memory_chrome.log
파일에 저장되는 내용:

--------------------------------------------------------------------------- 
2013-12-24 19:08:11.08 (1) 

iexplore.exe                  1836 Console                    1     27,908 K
iexplore.exe                  6764 Console                    1    175,692 K
--------------------------------------------------------------------------- 
2013-12-24 19:08:41.15 (2) 

iexplore.exe                  1836 Console                    1     27,908 K
iexplore.exe                  6764 Console                    1    178,324 K
--------------------------------------------------------------------------- 

실행되는 모습:


IE Process의 메모리가 증가하는지 쉽게 확인하는 법


Process Explorer 에서 iexplore.exe 프로세스를 찾아서 마우스로 오른쪽 클릭하고, Properties... 메뉴 선택.

Performance Graph 탭을 보면 IE Process만 사용하는 CPU, Private Bytes, I/O 를 볼 수 있다.



Memory Leak 확인 예제 #1

테스트한 브라우저: IE9

테스트 결과: 어느 정도 급격하게 증가한 이후에는 증가하지 않는다.

29.6 MB => 220.2 MB => 411.8 MB => 411.8 MB => 411.9 MB


<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
    function LeakMemory(){
        var parentDiv = document.createElement("div");
        parentDiv.onclick=function() {
          foo();
        };

        parentDiv.bigString =
          new Array(1000).join(new Array(20000).join("XXXXX"));

        alert('Leak Memory Done');
    }

</script>
</head>
<body>
<input type="button" value="Memory Leaking Insert" onclick="LeakMemory()" />
</body>
</html>



Memory Leak 확인 예제 #2

테스트한 브라우저: IE9

테스트 결과: 어느 정도 메모리가 증가한 이후로는 더 이상 증가하지 않았다. (메모리가 많이 증가했다가 alert 버튼을 누르고 나면 다시 원상태로 돌아옴.)

28.1 MB => 39.0 MB => 36.4 MB => 38.4 MB => 37.6 MB => 37.5 MB


<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
    function leak() {
      var e = document.createElement('div');
      var x = { elementReference: e };
      e.jsReference = x;
    }

    function test() {
      for (var i = 0; i < 1000000; i++)
        leak();
      alert('Done');
    }
</script>
</head>
<body>
<input type="button" value="Circular Reference" onclick="test()" />
</body>
</html>


Comments