가비지 콜렉션이란?
가비지 콜렉터가 더이상 사용되지 않는 메모리를 해제하는 것이다.
가비지 콜렉션 예시
아래 글에서의 예시인데, 이 글만으로는 이해하기 힘든 부분이 있어 설명을 추가해보았다.
자바스크립트의 메모리관리 - JavaScript | MDN
C 언어같은 저수준 언어에서는 메모리 관리를 위해 malloc() 과 free()를 사용한다. 반면, 자바스크립트는 객체가 생성되었을 때 자동으로 메모리를 할당하고 쓸모 없어졌을 때 자동으로 해제한
developer.mozilla.org
var x = {
a: {
b: 2
}
}; // 1
{ b: 2 } 오브젝트는 b 오브젝트, { a: {b: 2} } 오브젝트는 a 오브젝트라 하겠다.
메모리에 b 오브젝트를 참조하는 a 오브젝트가 생긴다. x 변수는 a 오브젝트를 참조한다.
가비지 콜렉션이 수행될 메모리는 없다.
var y = x; // 2
y 변수는 x의 값, 즉 a 오브젝트 를 참조한다.
x = 1; // 3
x 변수에 1을 할당한다. 이때, 원래 참조하던 메모리의 값을 지우고 값 1을 등록하는 것이 아니라, 값 1을 위한 새로운 메모리를 할당한다.
y는 여전히 a 오브젝트를 참조하고 있다.
var z = y.a; // 4
변수 z는 a 오브젝트의 프로퍼티 a를 참조한다.
y = "heyyy"; // 5
y는 새로운 값 "heyyy"를 참조한다. z가 여전히 a 오브젝트의 프로퍼티 a를 참조하고 있으므로 가비지 컬렉션이 수행되지 않는다.
z = null; // 6
z가 null 값을 참조하면서 a 오브젝트를 참조하는 변수는 하나도 없다. a 오브젝트, b 오브젝트에 대한 가비지 콜렉션이 수행된다.
가비지 콜렉션 알고리즘
옛날에는 가비지 콜렉션 알고리즘으로 Reference-counting 알고리즘이 쓰였다. 값을 참조하는 변수가 없으면 가비지 콜렉션을 수행하는 것인데, 이 알고리즘에는 순환 참조로 인한 메모리 누수 문제가 있다.
function f(){
var o = {};
var o2 = {};
o.a = o2; // o는 o2를 참조한다.
o2.a = o; // o2는 o를 참조한다.
}
f();
1번이 f 함수를 실행하는 중의 상태이고, 2번이 f 함수가 종료된 시점이다. 함수가 종료되면서 두 오브젝트를 참조하는 o와 o2 변수가 사라졌음에도, 서로가 서로를 참조하고 있다. 그래서 실제로는 사용되지 않는 메모리이지만 메모리가 반환되지 않는다.
이에 대한 대안으로 Mark-and-sweep 알고리즘을 사용한다. 이 알고리즘은 주기적으로 전역변수들의 집합인 roots부터 시작해서, 전역변수들이 참조하고 있는 오브젝트, 그리고 그 오브젝트가 참조하는 오브젝트를 탐색하며 "닿을 수 있음" 표시를 한다. 그리고 닿을 수 없는 오브젝트에 대해 가비지 콜렉션을 수행한다.
'JAVASCRIPT' 카테고리의 다른 글
DOM과 Virtual DOM (0) | 2022.01.16 |
---|---|
자바스크립트 Promise (0) | 2022.01.14 |
자바스크립트 Execution Context (0) | 2021.12.08 |
자바스크립트 변수 호이스팅 (0) | 2021.12.04 |
JavaScript Closure (0) | 2021.04.21 |