백본 뷰를 만들고 처리기를 이벤트에 연결하고 사용자 정의 클래스를 인스턴스화하는 매우 간단한 테스트 사례를 만들었습니다. 이 샘플에서 “제거”버튼을 클릭하면 모든 것이 정리되고 메모리 누수가 없어야합니다.
코드에 대한 jsfiddle은 다음과 같습니다. http://jsfiddle.net/4QhR2/
// scope everything to a function
function main() {
function MyWrapper() {
this.element = null;
}
MyWrapper.prototype.set = function(elem) {
this.element = elem;
}
MyWrapper.prototype.get = function() {
return this.element;
}
var MyView = Backbone.View.extend({
tagName : "div",
id : "view",
events : {
"click #button" : "onButton",
},
initialize : function(options) {
// done for demo purposes only, should be using templates
this.html_text = "<input type='text' id='textbox' /><button id='button'>Remove</button>";
this.listenTo(this,"all",function(){console.log("Event: "+arguments[0]);});
},
render : function() {
this.$el.html(this.html_text);
this.wrapper = new MyWrapper();
this.wrapper.set(this.$("#textbox"));
this.wrapper.get().val("placeholder");
return this;
},
onButton : function() {
// assume this gets .remove() called on subviews (if they existed)
this.trigger("cleanup");
this.remove();
}
});
var view = new MyView();
$("#content").append(view.render().el);
}
main();
그러나 Chrome 프로필러를 사용하여 이것이 사실인지 확인하는 방법을 잘 모르겠습니다. 힙 프로파일 러 스냅 샷에 표시되는 내용이 많으며, 무엇이 좋은지 나쁜지를 해독하는 방법을 모릅니다. 지금까지 살펴본 튜토리얼은 “스냅 샷 프로파일 러 사용”을 지시하거나 전체 프로파일 러의 작동 방식에 대해 매우 자세하게 설명합니다. 프로파일 러를 도구로 사용하는 것이 가능합니까? 아니면 전체가 어떻게 설계되었는지 이해해야합니까?
편집 : 다음과 같은 자습서 :
내가 본 것 중에서 더 강력한 자료를 대표합니다. 그러나 3 Snapshot Technique 의 개념을 소개하는 것 외에도 실용적인 지식 (나 같은 초보자에게)에 대해서는 거의 제공하지 않습니다. ‘DevTools 사용하기’튜토리얼은 실제 예제를 통해 작동하지 않으므로, 모호하고 일반적인 개념적인 개념 설명은 그다지 도움이되지 않습니다. ‘Gmail’예는 다음과 같습니다.
누수가 발견되었습니다. 이제 뭐?
프로파일 패널의 아래쪽 절반에서 누출 된 객체의 유지 경로를 검사합니다.
할당 사이트를 쉽게 유추 할 수없는 경우 (예 : 이벤트 리스너) :
JS 콘솔을 통해 보유 객체의 생성자를 계측하여 할당을위한 스택 추적을 저장합니다.
클로저를 사용하십니까? 적절한 기존 플래그 (예 : goog.events.Listener.ENABLE_MONITORING)를 활성화하여 생성 중에 creationStack 속성을 설정하십시오
나는 그것을 읽은 후에 더 혼란스러워합니다. 그리고 다시, 그냥 말해 것은 할 수 할 수 없는 상황을 어떻게 그들이 할 수 있습니다. 내 관점에서 볼 때 모든 정보는 모호하거나 이미 프로세스를 이해 한 사람에게만 의미가 있습니다.
이보다 구체적인 문제 중 일부는 아래 @Jonathan Naguin의 답변 에서 제기되었습니다 .
답변
메모리 누수를 찾는 좋은 워크 플로는 Loreena Lee와 Gmail 팀이 일부 메모리 문제를 해결하기 위해 처음 사용 하는 세 가지 스냅 샷 기술입니다. 단계는 일반적으로 다음과 같습니다.
- 힙 스냅 샷을 만듭니다.
- 물건을하십시오.
- 다른 힙 스냅 샷을 작성하십시오.
- 같은 것을 반복하십시오.
- 다른 힙 스냅 샷을 작성하십시오.
- 스냅 샷 3의 “요약”보기에서 스냅 샷 1과 2 사이에 할당 된 개체를 필터링하십시오.
귀하의 예를 들어, 시작 버튼의 클릭 이벤트가 발생할 때까지 백본 뷰 작성을 지연시키는 이 프로세스 ( 여기에서 찾을 수 있음)를 표시하도록 코드를 조정했습니다 . 지금:
- 이 주소 를 사용하여 로컬에 저장된 HTML을 실행하고 스냅 샷을 만듭니다.
- 시작을 클릭하여보기를 작성하십시오.
- 다른 스냅 샷을 찍습니다.
- 제거를 클릭하십시오.
- 다른 스냅 샷을 찍습니다.
- 스냅 샷 3의 “요약”보기에서 스냅 샷 1과 2 사이에 할당 된 개체를 필터링하십시오.
이제 메모리 누수를 찾을 준비가되었습니다!
몇 가지 다른 색상의 노드가 있습니다. 레드 노드는 Javascript에서 직접 참조하지 않지만 분리 된 DOM 트리의 일부이므로 활성 상태입니다. 트리에 Javascript에서 참조한 노드 (폐쇄 또는 변수 일 수 있음)가있을 수 있지만 우연히 전체 DOM 트리가 가비지 수집되지 못하게합니다.
그러나 노란색 노드는 Javascript에서 직접 참조합니다. 동일한 분리 된 DOM 트리에서 노란색 노드를 찾아 Javascript에서 참조를 찾으십시오. DOM 창에서 요소로 연결되는 일련의 속성이 있어야합니다.
특히 HTML Div 요소가 빨간색으로 표시되어 있습니다. 요소를 확장하면 “캐시”함수에 의해 참조되는 것을 볼 수 있습니다.
행을 선택하면 콘솔 유형 $ 0에 실제 기능과 위치가 표시됩니다.
>$0
function cache( key, value ) {
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
if ( keys.push( key += " " ) > Expr.cacheLength ) {
// Only keep the most recent entries
delete cache[ keys.shift() ];
}
return (cache[ key ] = value);
} jquery-2.0.2.js:1166
요소가 참조되는 곳입니다. 불행히도 할 수있는 일은 많지 않으며 jQuery의 내부 메커니즘입니다. 그러나 테스트 목적으로 함수를 이동하고 메소드를 다음과 같이 변경하십시오.
function cache( key, value ) {
return value;
}
이제 프로세스를 반복하면 빨간색 노드가 표시되지 않습니다 🙂
선적 서류 비치:
답변
다음은 jsfiddle의 메모리 프로파일 링에 대한 팁입니다. 다음 URL을 사용하여 jsfiddle 결과를 분리하면 모든 jsfiddle 프레임 워크가 제거되고 결과 만로드됩니다.
http://jsfiddle.net/4QhR2/show/
다음 문서를 읽을 때까지 타임 라인과 프로파일 러를 사용하여 메모리 누수를 추적하는 방법을 알 수 없었습니다. ‘객체 할당 추적기’라는 제목의 섹션을 읽은 후 ‘레코드 힙 할당’도구를 사용하고 일부 분리 된 DOM 노드를 추적 할 수있었습니다.
jQuery 이벤트 바인딩에서 Backbone 이벤트 위임 사용으로 전환하여 문제를 해결했습니다. 전화를 걸면 최신 버전의 Backbone이 자동으로 이벤트를 바인딩 해제한다는 것을 이해합니다 View.remove()
. 데모 중 일부를 직접 실행하면 식별 할 수있는 메모리 누수로 설정됩니다. 이 문서를 공부 한 후에도 여전히 질문이 없으면 여기에 질문하십시오.
https://developers.google.com/chrome-developer-tools/docs/javascript-memory-profiling
답변
기본적으로 힙 스냅 샷 내부의 개체 수를 확인해야합니다. 두 스냅 샷 사이에 객체 수가 증가하고 객체를 폐기 한 경우 메모리 누수가 발생합니다. 내 조언은 코드에서 분리되지 않은 이벤트 핸들러를 찾는 것입니다.
답변
자바 스크립트 메모리 누수를 찾는 데 도움이되는 Google 소개 동영상이 있습니다.
답변
개발자 도구에서 타임 라인 탭을 볼 수도 있습니다. 앱 사용을 기록하고 DOM 노드 및 이벤트 리스너 수를 주시하십시오.
메모리 그래프가 실제로 메모리 누수를 나타내는 경우, 프로파일 러를 사용하여 누수를 파악할 수 있습니다.
답변
당신은 또한 읽을 수 있습니다 :
http://addyosmani.com/blog/taming-the-unicorn-easing-javascript-memory-profiling-in-devtools/
크롬 개발자 도구의 사용법을 설명하고 힙 스냅 샷 비교 및 사용 가능한 다른 힙 스냅 샷보기를 사용하여 메모리 누수를 확인하고 찾는 방법에 대한 단계별 조언을 제공합니다.
답변
나는 힙 스냅 샷을 찍기위한 조언을 두 번째로, 메모리 누수를 탐지하는 데 탁월하며 크롬은 탁월한 스냅 샷 작업을 수행합니다.
내 학위 연구 프로젝트에서 ‘계층’에 구축 된 많은 데이터를 생성 해야하는 대화 형 웹 응용 프로그램을 작성 중이었습니다.이 계층 중 많은 계층이 UI에서 ‘삭제’되지만 어떤 이유로 메모리가 부족하지 않았습니다. 스냅 샷 도구를 사용하여 할당 취소하고 JQuery가 객체에 대한 참조를 유지하고 있음을 확인할 수있었습니다 (소스는 .load()
범위를 벗어나더라도 참조를 유지 이벤트 ). 이 정보를 한 손으로 내 프로젝트에 저장하면 다른 사람들의 라이브러리를 사용할 때 GC가 작업을 수행하지 못하게하는 참조가 남아있는이 문제가 있습니다.
편집 : 스냅 샷 작성 시간을 최소화하기 위해 수행 할 작업을 미리 계획하고 문제를 일으킬 수있는 원인을 가정하고 각 시나리오를 테스트하여 전후에 스냅 샷을 만드는 것이 유용합니다.