JavaScript 객체를 파괴하는 방법?


81

최근에 너무 많은 메모리를 소비하고 초당 10MB 씩 증가하는 애플리케이션 중 하나를 발견했습니다.

그래서 저는 JavaScript 객체와 변수를 파괴하는 가장 좋은 방법을 알고 싶습니다. 그래서 메모리 소비가 줄어들고 FF가 파괴되지 않습니다.

페이지를 다시로드하지 않고 8 초 간격으로 두 개의 JavaScript를 호출하고 있습니다.

function refresh() {
    $('#table_info').remove();
    $('#table').hide();
    if (refreshTimer) {
        clearTimeout(refreshTimer);
        refreshTimer = null ;
    }
    document.getElementById('refresh_topology').disabled=true; 
    $('<div id="preload_xml"></div>').html('<img src="pic/dataload.gif" alt="loading data" /><h3>Loading Data...</h3>').prependTo($("#td_123"));
    $("#topo").hide();
    $('#root').remove();
    show_topology();
}

어떤 변수로 인해 메모리 오버 헤드 와 메서드가 해당 프로세스의 실행을 중지 하는지 어떻게 알 수 있습니까?


1
클로저를 사용하여 코드의 일부를 분리하는 것을 고려 했습니까?
YS.

1
시도해 본 적이 있습니까? 사용처럼 obj = null?
Florian Margaine 2012

A) 무엇을 show_topology합니까? --- B) 당신이 추가 한 것들을 정리해 본 적이 #td_123있습니까? --- C) 어딘가에 이것의 라이브 버전이 있습니까?
Deestan

답변:


93

다음과 같이 모든 코드를 하나의 네임 스페이스에 넣을 수 있습니다.

var namespace = {};

namespace.someClassObj = {};

delete namespace.someClassObj;

delete키워드를 사용하면 속성에 대한 참조가 삭제되지만 낮은 수준에서 JavaScript GC (가비지 수집기)는 회수 할 개체에 대한 자세한 정보를 얻습니다.

또한 Chrome 개발자 도구를 사용하여 앱의 메모리 프로필과 축소해야하는 앱의 개체를 가져올 수 있습니다.


12
개발자 도구를 얻으려면 F12를 누르십시오. 프로필 탭으로 이동하고 시작을 클릭하여 프로필을 시작합니다. JS CPU, CSS Selector에서 프로파일 링을 할 수 있고 힙 스냅 샷을 찍을 수 있습니다.
Sarath 2012

3
또는 최근에 크롬은 JS 콘솔의 단어 성능을 입력
데이비드 모로에게

당연 할 수도 있지만 이름 공간에 "g"와 같은 이름을 지정하고 많은 입력을 절약 할 수 있습니다. var curItem = ... 대신 g.curItem = ...을 사용하고 입력을 저장하고 g = undefined가 모든 전역 메모리 할당을 지울 수 있도록합니다.
David Spector

31

개체를 삭제할 수 없으며 더 이상 참조가 없을 때 제거됩니다. 를 사용하여 참조를 삭제할 수 있습니다 delete.

그러나 객체에 순환 참조 를 만든 경우 몇 가지를 분리해야 할 수 있습니다.


2
가비지 수집기에서 포착하지 않는 순환 참조의 예를 추가 할 수 있습니까? 친구를 구하는 중! )
emilhem

@emilhem은 가비지 수집기를 참조 할 수 있으며 자신과 인터넷을 삭제합니다. 파열로 인해 CERN에서 블랙홀이 생성 될 수 있습니다. 그 예에 대해 생각해 보셨습니까?
El Mac

28

기존 답변은 문제를 해결하기위한 솔루션과 질문의 후반부를 제공했지만, 굵게 표시된 질문의 전반부에서 자기 발견 측면에 대한 답변을 제공하지 않습니다.

"어떤 변수가 메모리 오버 헤드를 유발하는지 어떻게 알 수 있습니까?"

3 년 전에는 강력하지 않았을 수 있지만 Chrome 개발자 도구 ' 프로필 '섹션은 이제 매우 강력하고 기능이 풍부합니다. Chrome 팀은이 를 사용하는 방법과 자바 스크립트에서 GC (가비지 수집)가 작동 하는 방식에 대한 통찰력있는 기사 를 보유하고 있습니다. 이는이 질문의 핵심입니다.

delete기본적으로 Yochai Akoka가 현재 받아 들여지는 답변의 뿌리 이므로 delete가 무엇을하는지 기억하는 것이 중요합니다. 다음 두 답변에서 GC 작동 방식에 대한 개념과 결합되지 않으면 관련이 없습니다. 객체에 대한 기존 참조가 있으면 정리되지 않습니다. 대답은 더 정확하지만 '삭제'를 작성하는 것보다 더 많은 생각이 필요하기 때문에 아마도 감사하지 않을 것입니다. 예, 가능한 해결책 중 하나는를 사용하는 것일 수 delete있지만 메모리 누수에 대한 다른 참조가 있는지 여부는 중요하지 않습니다.

또 다른 답변은 순환 참조를 적절하게 언급하며 Chrome 팀 문서는 원인을 확인하는 도구뿐만 아니라 훨씬 더 명확성을 제공 할 수 있습니다.

때문에 delete여기에 언급 된, 또한 자원을 제공하는 것이 유용 할 수 있습니다 삭제 이해 . 그것은 않지만 하지 정말 자바 스크립트의 가비지 컬렉터와 관련된 실제 솔루션의에 얻을.


9

모든 임시 개체가 전역 네임 스페이스 / 전역 개체 속성 대신 클로저 내부에 위치하고 작업이 끝나면 범위를 벗어나도록 코드를 구조화합니다. 나머지는 GC에서 처리합니다.


1

나는 이와 같은 문제에 직면했고 문제가있는 개체의 자식의 innerHTML을 간단히 변경하는 아이디어를 가지고있었습니다.

adiv.innerHTML = "<div...> the original html that js uses </div>";

더러워 보이지만 작동하면서 내 생명을 구했습니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.