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.