1. 쓰레기 재활용 메커니즘 -GC
JavaScript에는 자동 쓰레기 수집 메커니즘 (GC : Garbage Collection)이 있습니다. 즉, 실행 환경은 코드 실행 중에 사용되는 메모리 관리를 담당합니다.
원리 : 쓰레기 수집기는 주기적으로 (주기적) 사용 중이 아닌 변수를 찾은 다음 메모리를 해방시킵니다.
JavaScript Garbage Collection의 메커니즘은 매우 간단합니다. 더 이상 사용되지 않는 변수를 찾은 다음 점유하는 메모리를 제거하십시오. 그러나이 프로세스는 오버 헤드가 비교적 크기 때문에 실시간이 아니므로 쓰레기 수집기는 고정 시간 간격으로 주기적으로 실행됩니다 .
더 이상 사용되지 않는 변수는 수명주기를 끝내는 변수입니다. 물론, 그들은 로컬 변수 일 수 있습니다. 글로벌 변수의 수명주기는 브라우저가 페이지를 제거 할 때까지 종료되지 않습니다. 로컬 변수는 함수 실행 중에 만 존재하며,이 프로세스에서 해당 공간은 스택 또는 힙의 로컬 변수에 값을 저장하고 함수가 끝날 때까지 기능에 사용됩니다. 그러나 폐쇄의 내부 기능으로 인해 외부 기능은 결말로 간주 될 수 없습니다.
코드를 설명해 봅시다.
함수 fn1 () {var obj = {이름 : 'Hanzichi', age : 10};} 함수 fn2 () {var obj = {이름 : 'Hanzichi', Age : 10}; return obj;} var a = fn1 (); var b = fn2 ();코드가 어떻게 실행되는지 봅시다. 먼저, FN1 및 FN2라고하는 두 가지 함수가 정의됩니다. FN1이 호출되면 FN1 환경에 들어가면 메모리 저장소 개체 {이름 : 'Hanzichi', Age : 10}이 열립니다. 호출이 완료되고 FN1 환경이 출시되면 JS 엔진의 쓰레기 수집기가 메모리 블록을 자동으로 해제합니다. FN2가 호출되는 과정에서, 반환 된 객체는 글로벌 변수 B에 의해 가리키므로 메모리 블록이 해제되지 않습니다.
여기서 질문이 발생합니다. 어떤 변수가 쓸모가 없습니까? 따라서 쓰레기 수집기는 쓸모없는 변수를 추적해야하며 향후 메모리를 되 찾기 위해 더 이상 유용하지 않은 변수를 표시해야합니다. 태그에 사용되는 쓸모없는 변수에 대한 전략은 구현마다 다를 수 있으며,이를 수행하는 두 가지 방법은 마크 클리어런스 및 참조 계산입니다. 견적 계산은 그다지 일반적이지 않으며 마크 청소가 더 일반적으로 사용됩니다.
2. 명확한 마크
JS에서 가장 일반적으로 사용되는 쓰레기 수집 방법은 마크 제거입니다. 예를 들어, 변수가 환경에 들어가면 함수의 변수를 선언하면 변수를 "환경에 입력"으로 표시합니다. 논리적으로 말하면, 환경에 들어가는 변수가 차지하는 메모리는 실행 흐름이 해당 환경에 들어가는 한 사용될 수 있기 때문에 해제 될 수 없습니다. 가변이 환경을 떠나면 "환경 밖"으로 표시됩니다.
함수 test () {var a = 10; // 표시되어 있으시면 환경을 입력합니다. var b = 20; //가 표시되어 있고, 환경을 입력} test (); // 실행 후 A와 B가 표시되고 환경을 떠나 재활용됩니다.쓰레기 수집기가 실행되면 메모리에 저장된 모든 변수를 표시합니다 (물론 모든 마킹 방법을 사용할 수 있음). 그런 다음 환경에서 변수의 태그 (폐쇄)와 환경의 변수에 의해 참조 된 변수를 제거합니다. 이후에 표시된 변수는 환경의 변수가 더 이상 이러한 변수에 액세스 할 수 없기 때문에 삭제할 준비가 된 변수로 간주됩니다. 마지막으로, 쓰레기 수집가는 메모리 청소 작업을 완료하여 표시된 값을 파괴하고 그들이 차지하는 메모리 공간을 되 찾습니다.
지금까지 IE, Firefox, Opera, Chrome 및 Safari의 JS 구현은 Mark-Clearing Garbage Collection 전략 또는 유사한 전략을 사용하지만 쓰레기 수집의 시간 간격은 서로 다릅니다.
3. 인용 수
참조 수의 의미는 각 값이 참조되는 횟수를 추적하는 것입니다. 변수가 선언되고 기준 유형 값이 변수에 할당 될 때,이 값에 대한 참조 수는 1입니다. 동일한 값에 대해 다른 변수에 할당되면 값에 대한 참조 수가 1만큼 증가합니다. 반대로,이 값에 대한 참조를 포함하는 변수가 다른 값에 대한 참조 값이 1 값으로 감소하면, 다시 기억할 수 없다. 그것이 차지하는 공간은 되찾아 줄 수 있습니다. 이런 식으로, 다음에 쓰레기 수집가가 다시 실행되면, 0 참조로 값을 값을 값으로 만들어냅니다.
함수 test () {var a = {}; // a의 참조 수는 0 var b = a입니다. // a의 참조 수는 1 var c = a입니다. // a의 참조 수는 1이고 a의 참조 수는 1이고 a의 참조 수는 1이고 a의 참조 수는 2 var b = {}; // A의 참조 수는 1이고 A의 참조 수는 1}입니다.NetScape Navigator3은 참조 계산 전략을 사용한 최초의 브라우저 였지만 곧 심각한 문제인 순환 참조에 직면했습니다. 원형 기준은 객체 B에 대한 포인터를 포함하는 물체 A를 나타내고, 개체 B는 객체 A에 대한 참조를 포함합니다.
함수 fn () {var a = {}; var b = {}; A.Pro = B; b.pro = a;} fn ();위의 A와 B의 기준 시간은 2입니다. fn ()가 실행 된 후 두 객체 모두 환경을 떠났습니다. 마크 지우기 모드에는 문제가 없습니다. 그러나, 기준 계수 전략 하에서, A와 B의 기준 시간은 0이 아니기 때문에, 메모리는 쓰레기 수집기에 의해 수집되지 않습니다. FN 기능이 대량으로 호출되면 메모리 누출이 발생합니다. IE7 및 IE8에서 메모리는 급격히 상승합니다.
우리는 IE의 일부 객체가 기본 JS 객체가 아니라는 것을 알고 있습니다. 예를 들어, DOM 및 BOM의 객체는 C ++를 사용하여 COM 객체의 형태로 구현되며 COM 객체의 쓰레기 수집 메커니즘은 참조 계산 전략을 채택합니다. 따라서 IE JS 엔진이 태그 청산 전략을 채택하더라도 JS가 액세스 한 COM 객체는 여전히 참조 계산 전략을 기반으로합니다. 다시 말해, COM 객체가 IE에 관여하는 한 원형 참조 문제가 발생합니다.
var element = document.getElementById ( "some_element"); var myObject = new Object (); myObject.e = element.o = myObject;
이 예제는 DOM 요소와 기본 JS 객체 사이의 원형 기준을 만듭니다. 그중에서도 변수 myObject에는 요소 객체를 가리키는 요소라는 속성이 있습니다. 변수 요소에는 MyObject를 참조 할 O Back이라는 속성도 있습니다. 이 원형 기준으로 인해 예제의 DOM이 페이지에서 제거 되더라도 재활용되지 않습니다.
위의 예를 살펴보면 일부 학생들은 그것이 너무 약하다고 생각했습니다. 누가 그런 지루한 일을할까요? 사실, 우리는 그것을하고 있습니까?
window.onload = function auterfunction () {var obj = document.getElementById ( "요소"); obj.onclick = 함수 innerfunction () {};};이 코드는 괜찮은 것으로 보이지만 OBJ는 Document.GetElementById ( "요소")를 지칭하고 ONCLICK의 문서 메소드는 OBJ를 포함하는 외부 환경에서 독일 변수를 참조합니다. 그다지 숨겨져 있지 않습니까?
해결책
가장 쉬운 방법은 루프를 수동으로 회의하지 않는 것입니다. 예를 들어, 이제 기능이이를 수행 할 수 있습니다.
myObject.Element = null; element.o = null;
window.onload = function auterfunction () {var obj = document.getElementById ( "요소"); obj.onclick = 함수 innerfunction () {}; obj = null;};변수를 NULL로 설정한다는 것은 변수와 이전에 참조 한 값 사이의 연결을 차단하는 것을 의미합니다. 다음에 쓰레기 수집가가 실행되면이 값은 삭제되고 그들이 차지하는 메모리가 재활용됩니다.
IE9+는 DOM 메모리 누출을 유발하기위한 원형 기준이 없다는 점에 유의해야합니다. Microsoft가 최적화되었거나 DOM의 재활용 방법이 변경되었을 수도 있습니다.
4. 메모리 관리
1. 쓰레기 수집은 언제 트리거됩니까?
쓰레기 수집가는 주기적으로 실행됩니다. 할당 된 메모리가 매우 크면 재활용 작업이 매우 어려울 것입니다. 쓰레기 수집 시간 간격을 결정하는 것은 생각할 가치가있는 질문이됩니다. IE6의 쓰레기 수집은 메모리 할당에 따라 실행됩니다. 환경에 256 개의 변수, 4096 개 객체 및 64K 문자열이 있으면 쓰레기 수집기가 트리거됩니다. 그것은 매우 과학적으로 보이며 한 번 동안 한 번 호출 할 필요는 없습니다. 때로는 불필요합니다. 이런 식으로 주문형으로 전화하는 것이 좋지 않습니까? 그러나 환경에 변수가 너무 많아서 스크립트가 너무 복잡하고 정상적인 경우, 결과는 쓰레기 수집기가 항상 작동하므로 브라우저가 재생할 수 없습니다.
Microsoft는 IE7을 조정했습니다. 트리거 조건은 더 이상 고정되지 않고 동적으로 수정됩니다. 초기 값은 IE6과 동일합니다. 가비지 수집기에 의해 수집 된 메모리 할당이 프로그램이 차지하는 메모리의 15% 미만이면 대부분의 메모리를 재활용 할 수 없음을 의미합니다. 세트 쓰레기 수집 트리거 조건이 너무 민감합니다. 현재 거리 조건을 두 배로 늘리십시오. 수집 된 메모리가 85%보다 높으면 대부분의 메모리가 오래 전에 청소해야 함을 의미합니다. 현재 트리거 조건이 다시 설정됩니다. 이것은 쓰레기 재활용이 더 많은 기능을합니다
2. 합리적인 GC 솔루션
1) JavaScript 엔진의 기본 GC 솔루션은 (간단한 GC) : Mark and Sweep, I.E. :
2) GC 결함
다른 언어와 마찬가지로 JavaScript의 GC 정책은 한 가지 문제를 피할 수 없습니다. GC 일 때 보안상의 이유로 다른 운영에 대한 응답을 중지하십시오. JavaScript의 GC는 100ms 이상이며 일반 응용 프로그램에 적합하지만 JS 게임의 경우 높은 일관성이 필요한 응용 프로그램은 번거 롭습니다. 이것이 새로운 엔진이 최적화하는 데 필요한 것입니다. GC로 인한 장기 정지 응답을 피하십시오.
3) GC 최적화 전략
David 아저씨는 주로 두 가지 최적화 솔루션을 도입했으며 이는 가장 중요한 두 가지 최적화 솔루션입니다.
(1) GC)
이것은 Java 재활용 전략 아이디어와 일치합니다. 목적은 "임시"와 "지속적인"객체를 구별하는 것입니다. 더 많은 "임시 객체"영역과 적은 "임기 객체"영역을 재활용하면 매번 이동 해야하는 물체를 줄여서 매번 GC에 소비 된 시간을 줄입니다. 그림과 같이 :
여기에 추가해야 할 것은 임기 세대 객체의 경우 추가 오버 헤드가 있다는 것입니다. 젊은 세대에서 임시 세대로 마이그레이션하고 참조 된 경우 참조 포인팅도 수정해야합니다.
(2) 증분 GC
이 계획에 대한 아이디어는 매우 간단합니다. "매번 조금 치료하고 다음 번에 조금 처리하는 등"입니다. 그림과 같이 :
이 솔루션에는 짧은 시간이 걸리지 만 많은 중단이있어 컨텍스트 전환이 빈번한 문제가 발생합니다.
각 솔루션에는 해당 시나리오와 단점이 있으므로 실제 응용 분야에서는 실제 상황에 따라 솔루션이 선택됩니다.
예를 들어 : (객체/s) 비율이 낮을 때 GC 실행 빈도가 중단되고 간단한 GC가 더 낮습니다. 많은 객체가 오랫동안 "살아남은"경우 세대 처리의 장점은 크지 않습니다.
위의 기사는 Javascirp의 Garbage Collection Recycling 메커니즘이 내가 공유하는 모든 내용임을 포괄적으로 이해합니다. 나는 그것이 당신에게 참조를 줄 수 있기를 바랍니다. 그리고 당신이 wulin.com을 더 지원할 수 있기를 바랍니다.