function fors(){
obj_a = obj_b;
obj_b.attr = obj_a;
}
function fors(){
obj_b = {};
obj_b.attr = obj_b;
}
위의 두 가지는 매우 명백한 순환 참조 IE에서는 메모리 누수가 발생합니다. IE의 메모리 재활용 메커니즘으로 인해 메모리가 오랫동안 점유되어 해제될 수 없습니다.
하지만 클로저의 메모리 누수는 다소 숨겨져 있습니다. 클로저의 순환 참조는 간접적이기 때문입니다.
function iememery(){
var js_obj = document .createElement("div");
js_obj.oncontextmenu = function(){ return false;}
}
>
표면적으로는 순환 참조가 없습니다. 하지만 위의 내용은 클로저의 특성에 따라 내부 함수가 외부 함수의 변수 객체에 접근할 수 있는 권한을 가집니다. 따라서 iememery()가 실행되면
js_obj는 DOM 요소에 대한 참조입니다. DOM 요소는 오랫동안 웹 페이지에 남아 있으며 이 DOM 요소의 속성인 oncontextmenu도 내부 요소입니다. 함수 참조(클로저)이며 이 익명 함수는 js_obj와 숨겨진 연관(범위 체인)을 가지고 있습니다.
그래서 순환 참조가 형성됩니다. 즉,
js_obj.oncontextmenu가 js_obj를 간접적으로 참조합니다. 즉, 순환 참조입니다. 이 객체 속성의 속성이며 간접적으로 자신을 참조합니다.
순환 참조가 있는 한 IE에서는 메모리 누수가 발생합니다. Windows 작업 관리자를 열고 IE에서 이 코드가 포함된 HTML 페이지를 계속 새로 고쳐 Iexploer 프로세스의 메모리 사용량이 계속 증가하고 자동으로 재활용(낮춰짐)되지 않는지 확인하세요.
해결책:
function iememery(){
var js_obj = document. createElement("div");
js_obj.oncontextmenu = function(){ return false;} js_obj.oncontextmenu = null;//참조를 중단하려면 이 문장을 추가하세요.}
IE에서는 js 객체와 dom 객체 사이의 직접 순환 참조가 발생하고 이후에는 참조가 없습니다.
IE 6이라면 IE 프로세스가 종료될 때까지 메모리 누수가 발생합니다.
IE 7이라면 메모리 누수는 현재 페이지를 떠날 때까지
IE 8의 경우 현재 호환 모드인지 여부에 관계없이 GC 수집기가 메모리를 회수합니다.
기존 IE js 엔진의 GC 컬렉터는 js 객체만 처리할 수 있었고 DOM 객체는 처리할 수 없었습니다.