2011-08-04 7 views
7

방금 ​​전에 작성한 일부 자바 스크립트가 메모리 누수가있는 것으로 나타났습니다. jquery 덕분에 꽤 간단한 코드 조각이었습니다.하지만 taskmanager에서 실행되는 것을 볼 수 있으며 메모리 사용량은 천천히 4에서 40 바이트 사이를 클릭하십시오.자바 스크립트 메모리 누수

내가해서 getJSON를 통해 ASP MVC 컨트롤러/액션에서 일부 데이터를 던지고하고있어 모든 : 난 그냥 더 쉽게 문제를 확인하기 위해 타이머 값을 승진했습니다

$(document).ready(function() { 
    var olddata = ""; 
    window.setInterval(function() { 
     var options = JSON.stringify({ 
      orderby: "name" 
     }); 
     var params = { 
      options: options, 
      data: olddata ? JSON.stringify(olddata) : "" 
     }; 
     $.getJSON("/Home/GetTasks", params, function (json) { 
      olddata = json; 
      json = null; 
     }); 
     params = null; 
     options = null; 
    }, 1000); 
}); 

. 나는 분명히 여기 뭔가 잘못하고있다. 그러나 무엇을 볼 수 없다.

getJSON 호출을 정리해야합니까?

TIA.

+0

현재 비슷한 테스트를 수행하고 있습니다. 나는 다른 html 페이지로 XHR 호출을하는 간단한 html 페이지를 가지고있다. 다른 처리, DOM 조작 또는 스크립팅을 수행하지 않습니다. 내가 찾은 것은 XHR 호출로 인해 메모리가 누출되는 것입니다. Chrome의 누출은 매우 적습니다. IE는 적게, FF는 단순히 피를 흘립니다. 결론적으로, Ajax를 사용하면 브라우저에서 메모리 사용 공간이 약간 증가합니다. – Mrchief

+1

여기서 개선 할 수있는 한 가지는 'setInterval'에서 인라인 함수를 이동하는 것입니다. 그것을 정의하고 그 대신'setInterval'에서 핸들러를 사용하십시오. 누출을 어느 정도 완화 시키는데 도움이 될 것입니다. – Mrchief

+0

간격이 발생할 때마다 매개 변수와 옵션을 다시 정의하는 것을 중지 할 수도 있습니다. – sciritai

답변

6

실제로 메모리가 누출되었음을 어떻게 알 수 있습니까?

4 및 40 바이트와 같은 작은 숫자에서는 힙의 증가를 볼 수 있지만 힙의 새로운 블록 중 일부는 "무료"이며 향후 사용을 위해 사용할 수 있으므로 전체 응용 프로그램 메모리 사용량이 증가하는 동안 메모리 실제로 새는 것이 아니며 나중에 사용할 수 있으므로 영원히 성장하지는 않습니다.

실험의 전체 범위 인 경우 코드에 문제가 없습니다.

여기에는 세 가지 기능 클로저가 있습니다. $(document).ready() 클로저는 코드의 수명을 연장하지만 일회성 거래이므로 아무런 문제가 없어야합니다.

익명 함수가 setInterval()으로 전달되면 $(document).ready() 클로저가 계속 유지됩니다. setInterval() 익명 함수를 호출 할 때마다 새로운 지역 변수 집합을 가져오고 이전 호출이 완료 될 때 이전 변수를 릴리스하는 새 호출이어야합니다.

getJSON()에 전달 된 익명 함수를 setInterval을 익명 함수에 클로저를 생성하지만, 그렇게되면 그 폐쇄는 마지막으로해서 getJSON 함수 마감은과 setInterval() 익명 함수 클로저는 공개되어야한다 때까지.

내가 여기서 볼 수있는 유일한 폐쇄는 $(document).ready() 클로저로 의도 한 것이므로 한 번만 생성되므로 누출이 발생하지 않아야합니다.

getJSON 익명 함수의 모든 로컬 변수는 끝날 때 해제 될 예정입니다. 살아 남는해서 getJSON 호출의 유일한 데이터는 할당입니다 :

olddata = json; 

그러나 이전 데이터가 더 이상 쓰레기가 재활용을 위해 참조 있고 사용할 수 있도록 각 연속 할당은 이전 호출에서 데이터를 대체하지 않습니다 수집기.

여기에는 DOM 조작이 없으므로 DOM과 JS 사이에 교차 참조 또는 순환 참조의 기회가 없습니다.

필자의 결론은 누출되는 것을 볼 수 없다는 것입니다. 나는 임시 메모리를 사용하는 것을 많이 보았으므로 프로세스 메모리 사용량에서 볼 수있는 것이 단지 힙 증가 일 뿐이라고 생각합니다. 그러나 성장한 메모리가 결국에는 재사용 될 것입니다. 브라우저가 JSON 결과도 캐싱하는 경우 메모리 캐시 증가도 볼 수 있습니다.

불행히도 오늘날의 브라우저에서는 캐싱, 일반 힙 (heap) 등에서 사용되는 브라우저 메모리의 일시적인 확장에 비해 메모리 누수가 언제 발생하는지 파악하기가 어렵습니다. 극단적으로 모든 캐쉬를 매우 세밀하게 설정할 수 있습니다 작고 이것을 오랜 시간 (수십만 반복) 실행하십시오. 누출이 아니라면 메모리 사용은 결국 평평 해져야합니다. 누출 인 경우 메모리 사용은 상대적으로 선형 적으로 계속 증가해야합니다.

면책 조항 : 여기 한 면책 내가 jQuery를 기능 $.getJSON() 자체 누출 항상 AJAX 호출이 성공하지 못한 경우에도이 생성 폐쇄를 정리하는 방법으로 종료하지 않습니다 겠지이다 .