>  기사  >  웹 프론트엔드  >  JavaScript 메모리 관리 소개_javascript 기술

JavaScript 메모리 관리 소개_javascript 기술

WBOY
WBOY원래의
2016-05-16 16:09:40968검색

소개

C와 같은 저수준 언어에는 malloc() 및 free()와 같은 저수준 메모리 관리 기본 요소가 있습니다. 반면 JavaScript의 메모리 기본 요소는 변수(객체, 문자열 등)가 생성될 때 할당되고 더 이상 사용되지 않으면 "자동으로" 해제됩니다. 후자를 가비지 수집이라고 합니다. 이 "자동"은 혼란스럽고 JavaScript(및 기타 고급 언어) 개발자에게 메모리 관리에 대해 생각할 필요가 없다는 착각을 줍니다.

메모리 수명주기

어떤 프로그래밍 언어에 관계없이 메모리 수명 주기는 기본적으로 동일합니다.

1. 필요한 메모리를 할당하세요
2. 활용하세요(읽기, 쓰기)
3. 사용하지 않을 때는 풀어주세요 ps: "코끼리를 냉장고에 넣는다"와 같은 의미입니다

프로세스의 첫 번째와 두 번째 부분은 모든 언어에서 명확합니다. 저수준 언어에서는 마지막 단계가 명확하지만, 자바스크립트 같은 고급 언어에서는 마지막 단계가 명확하지 않습니다.

JavaScript 메모리 할당

변수 초기화

프로그래머가 할당에 대해 걱정하지 않도록 JavaScript에서는 변수를 정의할 때 메모리 할당을 완료합니다.

코드 복사 코드는 다음과 같습니다.

var n = 123; // 숫자 변수에 메모리 할당
var s = "azerty"; // 문자 유형 지정

var o = {
답: 1,
b: null
}; // 객체와 객체를 포함하는 변수에 대한 메모리를 할당합니다

var a = [1, null, "abra"]; // 배열 및 포함된 변수에 대한 메모리 할당(객체와 동일)
함수 f(a){
2를 반환합니다.
} // 함수(호출 가능 객체)에 메모리를 할당합니다

// 함수 표현식은 객체를 할당할 수도 있습니다
someElement.addEventListener('클릭', function(){
someElement.style.BackgroundColor = '파란색';
}, 거짓);

함수 호출을 통한 메모리 할당

일부 함수 호출로 인해 개체 메모리가 할당됩니다.

코드 복사 코드는 다음과 같습니다.

var d = new Date();
var e = document.createElement('div'); //DOM 요소 할당

일부 메소드는 새 변수나 새 객체를 할당합니다.

코드 복사 코드는 다음과 같습니다.

var s = "azerty";
var s2 = s.substr(0, 3); // s2는 새로운 문자열입니다
//문자열은 불변이기 때문에 JavaScript는 메모리를 할당하지 않고 0-3 범위만 저장할 수 있습니다.

var a = ["ouais ouais", "nan nan"];
var a2 = ["세대", "nan nan"];
var a3 = a.concat(a2); // 새 배열에는 배열 a와 배열 a2를 연결하는 4개의 요소가 있습니다.

가치의 사용

값을 사용하는 과정은 실제로 할당된 메모리를 읽고 쓰는 작업이므로 변수나 객체의 속성 값을 쓸 수 있고 함수 매개변수를 전달할 수도 있다는 의미입니다.

더 이상 필요하지 않은 메모리 해제

대부분의 메모리 관리 문제는 이 단계에서 발생합니다. 여기서 가장 어려운 작업은 할당된 메모리가 실제로 더 이상 필요하지 않다는 것을 찾는 것입니다. 개발자는 프로그램에서 더 이상 필요하지 않은 메모리 부분을 확인하고 이를 해제해야 하는 경우가 많습니다.

고급 언어 인터프리터에는 할당된 메모리가 더 이상 사용되지 않을 때 자동으로 해제될 수 있도록 메모리 할당 및 사용을 추적하는 것이 주요 작업인 "가비지 수집기"가 내장되어 있습니다. 특정 메모리 조각이 필요한지 여부를 알 수 없기 때문에 이 프로세스는 근사치입니다(특정 알고리즘으로 해결할 수 없음).

쓰레기 수거

위에서 언급했듯이 일부 메모리가 "더 이상 필요하지 않은"지 자동으로 찾는 문제는 판단할 수 없습니다. 따라서 가비지 수집 구현은 일반적인 문제를 제한된 범위에서만 해결할 수 있습니다. 이 섹션에서는 주요 가비지 수집 알고리즘과 그 제한 사항을 이해하는 데 필요한 개념을 설명합니다.

인용문

가비지 수집 알고리즘은 주로 참조 개념에 의존합니다. 메모리 관리의 맥락에서 객체가 다른 객체에 액세스할 수 있는 권한을 갖고 있는 경우(암시적 또는 명시적으로) 이를 다른 객체를 참조하는 객체라고 합니다. 예를 들어, Javascript 객체에는 프로토타입에 대한 참조(암시적 참조)와 해당 속성에 대한 참조(명시적 참조)가 있습니다.

여기서 "객체"라는 개념은 자바스크립트의 특별한 객체뿐만 아니라 함수 범위(또는 전역 어휘 범위)도 포함합니다.

참조카운팅 가비지 컬렉션

이것은 가장 간단한 가비지 수집 알고리즘입니다. 이 알고리즘은 "객체가 더 이상 필요하지 않은지 여부"의 정의를 "객체에 이를 참조하는 다른 객체가 있는지 여부"로 단순화합니다. 개체를 가리키는 참조가 없으면(참조 0개) 해당 개체는 가비지 수집 메커니즘에 의해 회수됩니다.

예를 들어

코드 복사 코드는 다음과 같습니다.

var o = {
답: {
b:2
}
}; // 두 개의 개체가 생성되고, 하나는 다른 개체의 속성으로 참조되고, 다른 하나는 변수 o
에 할당됩니다. // 분명히 그 중 어느 것도 가비지 수집될 수 없습니다
var o2 = o; // o2 변수는 "이 객체"에 대한 두 번째 참조입니다.

o = 1; // 이제 "이 객체"의 원래 참조 o가 o2로 대체됩니다.

var oa = o2.a; // "이 객체"의 속성 참조

// 이제 "이 객체"에는 두 개의 참조가 있습니다. 하나는 o2이고 다른 하나는 oa

o2 = "yo"; // 이제 원본 객체에는 참조가 없습니다

// 그는 가비지 수집될 수 있습니다
// 그러나 해당 속성 a의 객체는 여전히 oa에서 참조되므로 아직 재활용할 수 없습니다.

oa = null; // 이제 a 속성을 가진 객체도 참조가 없습니다

// 가비지 수집 가능

제한: ​​순환 참조

이 간단한 알고리즘의 한계는 한 객체가 다른 객체를 참조하는 경우(순환 참조 형성) 해당 객체가 "더 이상 필요하지 않을" 수 있지만 재활용되지 않는다는 것입니다.


코드 복사 코드는 다음과 같습니다.
함수 f(){
var o = {};
var o2 = {};
o.a = o2; // o 참조 o2
o2.a = o; // o2는 o를 참조합니다
"azerty"를 반환합니다.

}

에프();

// 두 개의 객체가 생성되고 서로 참조하여 루프를 형성합니다
// 호출된 후에도 함수 범위를 벗어나지 않습니다.
// 따라서 더 이상 유용하지 않으며 재활용할 수 있습니다.
// 그러나 참조 카운팅 알고리즘은 모두 서로에 대한 참조가 하나 이상 있다는 점을 고려하므로 재활용되지 않습니다.

실제 사례

IE 6, 7은 DOM 객체에 대한 참조 계산 재활용을 수행합니다. 이들의 일반적인 문제는 메모리 누수입니다.


코드 복사 코드는 다음과 같습니다.
var div = document.createElement("div");
div.onclick = 함수(){
doSomething();
}; // div에는 onclick 이벤트 처리 속성에 대한 참조가 있습니다
// 이벤트 핸들러에는 함수 범위에서 액세스할 수 있는 div에 대한 참조도 있습니다.
// 이 순환 참조로 인해 두 개체가 모두 가비지 수집되지 않습니다.

표시 및 지우기 알고리즘

이 알고리즘은 "객체가 더 이상 필요하지 않은지 여부"에 대한 정의를 "객체를 얻을 수 있는지 여부"로 단순화합니다.

이 알고리즘은 루트(Javascript에서는 루트가 전역 개체)라는 개체를 설정한다고 가정합니다. 주기적으로 가비지 수집기는 루트에서 시작하여 루트에서 참조되는 모든 개체를 찾은 다음 이러한 개체가 참조하는 개체를 찾습니다... 루트에서 시작하여 가비지 수집기는 얻을 수 있는 모든 개체와 모든 개체를 찾습니다. 얻을 수 없는 것입니다.

이 알고리즘은 이전 알고리즘보다 낫습니다. "참조가 0인 개체"는 항상 얻을 수 없지만 그 반대가 반드시 참인 것은 아니기 때문입니다. "순환 참조"를 참조하세요.

2012년 현재 모든 최신 브라우저는 표시 및 청소 가비지 수집 알고리즘을 사용합니다. JavaScript 가비지 수집 알고리즘의 모든 개선 사항은 마크 스윕 알고리즘의 개선 사항을 기반으로 하며 마크 스윕 알고리즘 자체와 "개체가 더 이상 필요하지 않은지 여부"에 대한 단순화된 정의를 개선하지 않습니다.

순환 참고는 더 이상 문제가 되지 않습니다

위의 예에서는 함수 호출이 반환된 후 전역 개체에서 두 개체를 가져올 수 없습니다. 따라서 가비지 수집기에 의해 수집됩니다.
두 번째 예에서는 div와 해당 이벤트 핸들러가 루트에서 연결할 수 없으면 가비지 수집기에 의해 수집됩니다.

제한 사항: 객체에 명시적으로 접근할 수 없어야 합니다

이는 제한 사항이지만 이를 초과하는 경우가 거의 없기 때문에 실제로 가비지 수집 메커니즘에 관심을 갖는 사람은 거의 없습니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.