[javascript] JavaScript 가비지 수집이란 무엇입니까?

JavaScript 가비지 수집이란 무엇입니까? 더 나은 코드를 작성하기 위해 웹 프로그래머가 JavaScript 가비지 콜렉션에 대해 이해하는 것이 중요합니까?



답변

에릭 리퍼 트 ​​(Eric Lippert)는 이 주제에 대한 자세한 블로그 게시물을 작성했습니다 ( VBScript와 비교 ). 보다 정확하게, 그는 JavaScript와 매우 유사하지만 Microsoft가 자체 ECMAScript를 구현 한 JScript 에 대해 썼습니다 . Internet Explorer의 JavaScript 엔진에서 대부분의 동작이 동일하다고 가정 할 수 있습니다. 물론 구현은 브라우저마다 다르지만 여러 일반적인 원칙을 취하여 다른 브라우저에 적용 할 수 있다고 생각합니다.

해당 페이지에서 인용 :

JScript는 비 생성 마크 앤 스윕 가비지 수집기를 사용합니다. 다음과 같이 작동합니다.

  • “범위 내”인 모든 변수를 “스 캐빈 저”라고합니다. 스 캐빈 저는 숫자, 개체, 문자열 등을 가리킬 수 있습니다. 스 캐빈 저 목록을 유지합니다. 변수가 범위에 도달하면 변수가 스캐브 목록으로 이동하고 범위를 벗어날 때 스캐브 목록에서 변수가 이동합니다.

  • 때때로 가비지 수집기가 실행됩니다. 먼저 모든 객체, 변수, 문자열 등에 GC가 추적하는 모든 메모리에 “마크”를 표시합니다. (JScript는 내부적으로 VARIANT 데이터 구조를 사용하며 해당 구조에는 사용되지 않는 추가 비트가 많이 있으므로 그중 하나만 설정합니다.)

  • 둘째, 청소부에서 표시를 제거하고 청소부 참조의 전 이적 폐쇄를 제거합니다. 따라서 scavenger 객체가 nonscavenger 객체를 참조하는 경우 비 scavenger 및 참조하는 모든 비트를 지 웁니다. (저는 이전 게시물과 다른 의미로 “폐쇄”라는 단어를 사용하고 있습니다.)

  • 이 시점에서 우리는 여전히 표시된 모든 메모리가 범위 내 변수의 경로에 도달 할 수없는 할당 된 메모리라는 것을 알고 있습니다. 이러한 객체는 모두 자체적으로 분해되도록 지시되어있어 순환 참조를 파괴합니다.

가비지 컬렉션의 주요 목적은 프로그래머를 허용하는 것입니다 되지 는 적어도 어떻게 가비지 컬렉션 작품의 거친 생각을 가지고 항상 도움이됩니다 – 물론 전혀 때때로이 피 년대 불구하고, 자신이 만든 객체와 사용의 메모리 관리에 대한 걱정에 .

과거 메모 : 이전 버전의 답변은 delete운영자 를 잘못 참조했습니다 . JavaScript 에서 delete연산자는 객체에서 속성을 제거하며delete C / C ++ 와는 완전히 다릅니다 .


답변

DOM 객체가 관련된 순환 참조에주의하십시오 :

JavaScript의 메모리 누수 패턴

객체에 대한 활성 참조가없는 경우에만 메모리를 회수 할 수 있습니다. 일부 JS 엔진은 내부 함수에서 실제로 참조되는 변수를 확인하지 않고 둘러싸는 함수의 모든 로컬 변수를 유지하기 때문에 클로저 및 이벤트 핸들러의 일반적인 함정입니다.

다음은 간단한 예입니다.

function init() {
    var bigString = new Array(1000).join('xxx');
    var foo = document.getElementById('foo');
    foo.onclick = function() {
        // this might create a closure over `bigString`,
        // even if `bigString` isn't referenced anywhere!
    };
}

순진한 JS 구현은 bigString이벤트 핸들러가있는 한 수집 할 수 없습니다 . 이 예를 들어 문제 설정 해결 방법에는 여러 가지가 있습니다 bigString = null의 끝은 init()( delete것이다 지역 변수와 함수 인수하지 작업 : delete개체를 삭제합니다 속성, 변수 개체에 액세스 할 수 없습니다 – 엄격 모드에서 ES5가도를 던질 것이다 ReferenceError당신이 시도하는 경우 지역 변수를 삭제하십시오!).

메모리 소비를 걱정하는 경우 가능한 한 불필요한 클로저를 피하는 것이 좋습니다.


답변

블로그에서 가져온 좋은 인용문

DOM 구성 요소는 JScript 구성 요소와 마찬가지로 “가비지 수집”으로, 구성 요소 중 하나에서 개체를 만든 다음 해당 개체를 추적하지 않으면 결국 정리됩니다.

예를 들면 다음과 같습니다.

function makeABigObject() {
var bigArray = new Array(20000);
}

해당 함수를 호출하면 JScript 구성 요소는 함수 내에서 액세스 할 수있는 객체 (이름이 bigArray)를 만듭니다. 그러나 함수가 리턴 되 자마자 더 이상 참조 할 수있는 방법이 없기 때문에 bigArray를 “잃어 버렸습니다”. JScript 구성 요소는 사용자가 구성 요소를 잃어 버렸음을 인식하여 bigArray를 정리하여 메모리를 회수합니다. DOM 구성 요소에서도 동일한 종류의 기능이 작동합니다. document.createElement('div'), 또는 이와 유사한 것을 말하면 DOM 구성 요소가 객체를 생성합니다. 어떻게 든 그 객체를 추적하지 못하면 DOM 구성 요소가 관련을 정리합니다.


답변

내가 아는 한, JavaScript 객체는 객체에 대한 참조가 없을 때 주기적으로 가비지 수집됩니다. 자동으로 발생하지만 C ++ 수준에서 작동 방식에 대해 더 자세히 알고 싶다면 WebKit 또는 V8 소스 코드를 살펴 보는 것이 좋습니다.

일반적으로 IE 5.5 및 이전 버전의 IE 6과 같은 이전 브라우저 및 현재 버전과 같은 오래된 브라우저에서 클로저는 체크하지 않으면 메모리를 소모하는 순환 참조를 생성합니다. 클로저에 대한 특별한 경우에는 dom 객체에 대한 JavaScript 참조를 추가하고 JavaScript 객체를 다시 참조하는 DOM 객체에 객체를 추가했을 때였습니다. 기본적으로 그것은 수집 될 수 없으며 결국 충돌을 일으키기 위해 반복되는 테스트 응용 프로그램에서 OS가 불안정하게됩니다. 실제로 이러한 누출은 일반적으로 작지만 코드를 깨끗하게 유지하려면 DOM 객체에 대한 JavaScript 참조를 삭제해야합니다.

일반적으로 delete 키워드를 사용하여 특히 모바일 웹 개발에서 수신하고 처리해야하는 JSON 데이터와 같은 큰 객체를 즉시 역 참조하는 것이 좋습니다. 이것은 GC의 다음 스윕이 해당 오브젝트를 제거하고 메모리를 비우도록합니다.


답변

가비지 수집 (GC)은 더 이상 필요없는 객체를 제거하여 자동 메모리 관리의 한 형태입니다.

메모리와 관련된 모든 프로세스는 다음 단계를 수행하십시오.

1-필요한 메모리 공간을 할당하십시오

2-일부 처리 수행

3-이 메모리 공간을 비우십시오

더 이상 필요하지 않은 객체를 감지하는 데 사용되는 두 가지 주요 알고리즘이 있습니다.

참조 카운트 가비지 콜렉션 :이 알고리즘은 “더 이상 오브젝트가 필요하지 않음”의 정의를 “오브젝트가 참조하는 오브젝트가없는 오브젝트”로 정의하며, 참조 점이 없으면 오브젝트가 제거됩니다.

Mark-and-Sweep 알고리즘 : 각 객체를 루트 소스에 연결합니다. 어떤 객체도 루트 나 다른 객체에 연결되지 않습니다. 이 개체는 제거됩니다.

현재 두 번째 알고리즘을 사용하는 최신 브라우저.


답변

“컴퓨터 과학에서 가비지 수집 (GC)은 자동 메모리 관리의 한 형태입니다. 가비지 수집기 또는 수집기 만 가비지 또는 응용 프로그램에서 다시 액세스하거나 변경하지 않는 개체가 사용한 메모리를 회수하려고 시도합니다.”

모든 JavaScript 엔진에는 자체 가비지 수집기가 있으며 다를 수 있습니다. 대부분의 경우 그들이해야 할 일을하기 때문에 처리 할 필요가 없습니다.

더 나은 코드를 작성하는 것은 주로 프로그래밍 원칙, 언어 및 특정 구현을 얼마나 잘 알고 있는지에 달려 있습니다.


답변

JavaScript 가비지 수집이란 무엇입니까?

이것을 확인 하십시오

더 나은 코드를 작성하기 위해 웹 프로그래머가 JavaScript 가비지 콜렉션에 대해 이해하는 것이 중요합니까?

Javascript에서는 메모리 할당 및 할당 해제에 신경 쓰지 않습니다. 모든 문제는 Javascript 인터프리터에게 요구됩니다. Javascript에서 누수가 여전히 가능하지만 해석기의 버그입니다. 이 주제에 관심이
있으시면 www.memorymanagement.org를 참조하십시오.