몇 일전 가비지 컬랙션에 대해서 포스팅할때 함께 기재할 메모리 테스트 부분에 대한 결과입니다.
이미지 첨부할게 너무 많아 PDF로 만들어서 첨부합니다.

도움이 될련지는 모르겠습니다.

테스트 코드 역시 첨부합니다.
테스트 코드는 IE 8의 순환참조에 대한 메모리 누수 마이그레이션 팁에 대한 내용을 실제로 구현 테스트 해 본것입니다.  실제로 테스트 코드와 같은 패턴의 사용은 메모리 IE에서 메모리 누수의 심각성을 보여줍니다.

IE Circular-Memory-leak Magration

메모리 누수 테스트 결과

테스트 코드

도움이 얼마나 될른지는 모르겠습니다. ^^
순환참조에 대한 경각심 정도는 불러 일으킬 수 있지 않을까 싶기도 하네요.


신고
Posted by Rhio.kim
부제 : garbage collection in javascript
자바스크립트 어플리케이션 메모리 관리라기 보다 가비지 컬랙션(Gabege Collection)과 클로져(closure)와 순환참조(circular reference) 의 관계에 대한 글에 가깝습니다.


중간 중간 정리하면서 가비지 컬랙션에 대한 참조한 블로그가 있었는데 까묵었습니다. ^-^;


간단 명료하게 결론부터 정리합니다.
Javascript RIA 개발 시 간과해서는 안되는 중요한 부분중에 한가지 입니다. 
바로 메모리 관리 Memory Management입니다.


  이미 여러 javascript로 RIA 개발 경험이 있는 개발자라면 뼈저리게 느끼고 있을 것입니다.
못느꼇다면 꼭 한번 브라우저를 띄우고 개발해 놓은 요소들을 메모리 테스트를 해보시기 바랍니다.

  그리고 윈도우 어플리케이션 개발자라면 이 메모리 관리에 대해서 매우 예민한 부분이 아닐 수 없습니다.  윈도우 어플리케이션도 아닌데 메모리 관리를 해줘야 한다니 그냥 웃고 넘어갈 분들도 계시겠지만 RIA 개발하려는 모든 분들께 메모리 관리에 대한 중요성을 전달해 주고 싶습니다.


가비지 컬랙션(Garbage Collection) ?
 힙heap영역에 할당된 더 이상 사용되지 않는 메모리인 가비지garbage를 가비지 컬랙터garbage collector가 다른 객체가 사용할 수 있도록 정리하는 것을 말합니다.

객체가 가리키는 참조 변수가 null이 지정되거나 객체가 더 이상 참조하지 않게 되었을 때 가비지 컬랙터의 후보가 되며 이러한 객체들은 가비지 컬랙터에 의해 메모리를 반환하게 됩니다.


가비지 컬랙션의 대상
1. 객체에 null 값이 대입되었을 때
    e.g.   var dat = new Date();
                  dat = null;
2. 참조변수에 다른 객체가 대입될 때
    e.g.   var dat = document.getElementById(‘rhio’);
                  dat = 29;
3. 메소드의 수행이 끝났을 때
    e.g.   function func() {
            var dat = document.getElementById(‘rhio’);
            //do something
          }

가비지 컬랙션과 순환참조에 대한 좋은 글  옷장수님 블로그#가비지 컬렉션의 이해

사용자 삽입 이미지
자바의 가비지 컬렉션은 자바가상머신Java Vitural Machine에서 알아서 처리하지만 개발자에 의해 직접 가비지 컬랙션을 수행 요청을 할 수 있습니다.  하지만 javascript의 경우에는 따로 개발자에 의해 가비지 컬랙션의 작업 수행 요청할 수 있는 매커니즘이 존재하지 않습니다.

Javascript는 주기적으로 가비지 컬랙션의 대상에 대한 리소스 반환 작업을 수행하게 됩니다.

IE 브라우저의 경우 순환참조Circular Reference 발생과  클로져 형성으로 메모리 누수에 대한 심각한 문제가 시작됩니다.   Javascript에서의 순환참조(Circular Reference)라 함은 Javascript 객체가 DOM 객체에 대한 레퍼런스를 포함하고 그 DOM 객체가 javascript 객체의 레퍼런스를 포함할 때를 말합니다.

위의 문단이 자바스크립트에만 순환참조가 있다라는 글로 오해될 수 있을 것 같아 살짝 수정 및 아래 내용을 추가합니다.  일반적인 순환참조(circular refrenece)에 대한 설명이 더욱 필요할 것 같네요.  (옷장수님이 의견 주셨습니다.)

일반적인 순환참조(Circular Reference)란?
참고 :
    http://en.wikipedia.org/wiki/Circular_reference
    http://en.wikipedia.org/wiki/Reference_counting


사용자 삽입 이미지

위의 예제는 흔히 우리가 알고 있는 javascript의 순환참조가 발생되면서 메모리 누수현상을 단편적으로 설명할 수 있는 예시가 됩니다.

div는 DOM 객체의 레퍼런스를 담고 있습니다. 이 DOM 객체를 outerFn 가 첫번째 인자로 취하여 DOM 객체에 func라는 프로퍼티property  javascript의 익명함수anonymous function 를 참조reference하게 합니다.

이 자체가 메모리 누수라 할 수는 없지만, 위와 같은 패턴은 경우에 따라(위와 같은 작업이 반복 적으로 수행될 때) 심각한 누수 현상을 발생할 수 있습니다.  이 말은 곧 가비지 컬랙션에 의해서 메모리 반환을 하지 못하는 상황에 빠지게 됩니다.

  Javascript의 가비지 컬랙터의 경우 클로져가 형성된 것들을 관리하며 혼돈하지 않아 가비지 컬랙션에 대해 메모리 반환을 하지만 불행히 IE의 경우 DOMJScript가 관리하지 않아 위의 예시와 같은 순환참조와 클로져에 대해 몹시 둔감합니다.  그만큼 메모리 누수 현상이 매우 심각합니다.

 
이번 IE8이 릴리즈 되면서 그에 대한 마이그레이션 팁이 나왔습니다. 그 역시 DOM과 Javascript의 순환참조에 대한 이슈를 대부분 언급하고 있습니다.  그에 대한 테스트와 테스트 결과에 대해서 다음에  간단한 포스팅을 하도록 하겠습니다.


참고
http://www.crockford.com/javascript/memory/leak.html
http://www-128.ibm.com/developerworks/web/library/wa-memleak/

신고
Posted by Rhio.kim
자바스크립트 메모리 누수 디텍터

IE6에서 아래와 같이 수행하면 메모리 누수가 발생합니다.

사용자 삽입 이미지













IE 팀에서는 이런 구조에서 발생하는 메모리 누수 문제를 해결하기 위해서 열심히 노력하고 있습니다.
초기 IE6 버전에서는 Javascript와 DOM Object 에서의 모든 순환참조(circular reference)에서 메모리 누수가 발생했었습니다.

IE7 에서는 이런 문제가 많이 해소 되었지만 많은 개발자에 의해서 그렇지 못한 점들을 계속 지적받고 있습니다.

설치 방법
다운로드 : download link
Tools->Toolbars->Explorer Bar > "js memory leaks detector"
사용자 삽입 이미지

























Tools->Internet Options->Advanced->Browsing
-> Disable script debugging
사용자 삽입 이미지

































메모리 누수가 발생한 지점을 찾아줍니다.
사용자 삽입 이미지


메모리 누수 관련 글

출처 : http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector.aspx
신고
Posted by Rhio.kim
사용자 삽입 이미지
Ajax 개발을 하면서 가장 많이 사용하는 프로퍼티중의 하나입니다.

서버에서 HTML로 생성해주거나 혹은 데이터를 html 스트링으로 변환하여 해당 엘리먼트에

Element의 프로퍼트(property)인 innerHTML에 string을 치환하게 됩니다.

비어져 있는 엘리먼트일 수도 있고 그렇지 않는 경우도 있습니다.

DOM을 일일이 생성하는 것보다 innerHTML이 간단하기 때문에 많이들 사용하지만

이렇게 innerHTML을 자주 사용하는 프로퍼티인데 하지만 이를 사용할 때 문제가 되는 사항이 많이 있습니다.

그래서 유의해서 사용해야합니다.


1. 이미 innerHTML에 어떤 Element 구조가 형성되어 있을 때 해당 엘리먼트에 innerHTML을 하게 되면
기존에 있던 구조가 모두 없어져 버리게 됩니다.
만약에 그 구조안에 이벤트 헨들러를 등록했었다면 몇몇 브라우저에서는 메모리 누수가 발생합니다.

2. DOM 엘리먼트를 참조는 되돌릴 수가 없습니다.

3. 모든 브라우저의 모든 엘리먼트에서 innerHTML 프로퍼티를 사용하여 설정할 수 없습니다.
예를 들어 IE에서는 table의 row 엘리먼트에는 설정할 수 없다는 것입니다.

4. 익스플로러에서는 innerHTML속성을 이용해 script-injection 공격을 할 수 있습니다.
익스플로러에는 스크립트 태그에 defer 속성이 있는데요.
이를 이용해 <script src="" defer></script>를 이용하면 외부 script 로딩을 해 여러가지 공격이 가능합니다.

뭐 더 생각해보면 많을 것 같습니다.

FireFox에서는 파이어버그를 이용해서 다양한 동적인 지원과 디버깅을 지원하는데요.
전문가들에게는 이게 해킹의 수단이 될 수도 있습니다.
신고
Posted by Rhio.kim