본문 바로가기

javascript

IE Javascript Memory Leak


참고 : http://www.crockford.com/javascript/memory/leak.html

Internet Explorer DOM 객체에 대하여 메모리 누수가 발생한다. (IE8에서는 개선 되었음)

Div Layer에 동적으로 Flash를 바꿔 낀다고 가졍한다.

1번 Flash는 작업관리자 IExplorer에서 메모리 확인 결과 100mb
2번 Flash는 작업관리자 IExplorer에서 메모리 확인 결과 200mb

이 나온다고 가정하면... 코드는 아래와 같다.

function getFlash(code){
    var sTag = ''
    var obj = document.getElementById("FlashObject");
    if(code === "A"){
        sTag = ''
            + ' <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'
            + ' id="a" width="887" height="599"'
            + ' codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">'
            + ' <param name="movie" value="a.swf" />'
            .... 생략 ....
    }else{
        sTag = ''
            + ' <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'
            + ' id="b" width="887" height="599"'
            + ' codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">'
            + ' <param name="movie" value="b.swf" />'
            .... 생략 ....
    }
    obj.innerHTML = sTag;
}

Div Layer "FlashObject"에 초기에 b.swf를 로딩하게 되면 작업관리자 IExplorer메모리는 200mb까지 할당된다.

그 상태에서 Div Layer "FlashObject"에 초기에 a.swf를 로딩하게 되면 작업관리자 IExplorer메모리는 순수 a.swf에 해당하는 메모리 100mb을 할당하지 않고 b.swf에 해당하는 메모리 + a.swf에 대항하는 메모리 총 300mb을 할당하는 모습을 볼수 있다. 이 구조를 계속 반복하게 되면 메모리 해제는 하지 못하고 누적되어 브라우저가 죽어버릴 것이다. 

위 사항을 해결할 수 있는 방법으로는 purge함수를 만들어 사용할 수 있다.

purge함수는 DOM Element 인자로 받는다. Element의 Attributes를 루프를 돌면서, 함수를 찾으면 null로 만들어 순환구조를 끊고 메모리가 교정될 수 있도록 한다. 함수는 또한 모든 하위 Element에도 같은 작용을 해서 closure가 잘 제거 되도록 한다. purge함수는 모질라와 오페라에는 아무런 해가 없으며 IE에서만 작용한다. purge함수는 Element가 removeChild메소드나 innerHTML속성으로 삭제되기 전에 호출되어야 한다.

function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
     a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
     }
}

function getFlash(code){
    var sTag = ''
    var obj = document.getElementById("FlashObject");
    if(code === "A"){
        sTag = ''
            + ' <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'
            + ' id="a" width="887" height="599"'
            + ' codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">'
            + ' <param name="movie" value="a.swf" />'
            .... 생략 ....
    }else{
        sTag = ''
            + ' <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'
            + ' id="b" width="887" height="599"'
            + ' codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">'
            + ' <param name="movie" value="b.swf" />'
            .... 생략 ....
    }
    purge(obj);
    obj.innerHTML = sTag;
}

'javascript' 카테고리의 다른 글

jQuery 1.4 버전 추가 기능  (0) 2010.02.03
이미지 링크 스타일 지정  (0) 2008.05.30
XML의 손쉬운 DOM 해석  (0) 2008.05.13