garbage collection이란?
메모리 관리 기법 중의 하나로, 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게 된 영역을 해제하는 기능이다.
메모리 관리?
- gif와 같이 컴퓨터는 우리가 작성한 변수, 함수, 객체들을 메모리에 할당한다. 하지만 계속 할당만 해서 메모리가 꽉 차게되면 작업중인 프로그램이 느려지고 결국은 강제종료되는 현상이 일어나게됩니다.
- 가상메모리도 메모리 관리를 위한 기법 중 하나입니다.

- 리스프라는 프로그래밍 언어의 문제를 해결하기 위해 존 매카시가 개발
- C, C++ 등의 프로그래밍 언어는 수동 메모리 관리를 가정하고 설계되었다. (
malloc()
,free()
)
- Jave, C# 같은 언어들은 처음부터 GC 기법을 염두에 두고 설계되어, 언어 정의에 GC이 포함되어 있다. 자바스크립트도 마찬가지입니다.
수동으로 메모리를 관리하는 방식에서 프로그래머가 까먹고 해제하지 못했을 때, 혹은 실수가 발생했을 때 아래와 같은 버그가 발생하게 된다.
- 메모리 누수(memory leak)
- 더 이상 필요하지 않은 메모리가 정리되지 않고 남아있는 버그
- 메모리 누수의 반복되면 메모리 고갈로 프로그램이 중단될 수 있다.

- 유효하지 않은 포인터 (Dangling Pointer)
- 이미 해제된 메모리에 접근하는 버그
- 댕글링 포인터인 메모리 접근 시 프로그램이 예측 불가능한 동작을 하게 되는 위험이 있다.
- 이중 해제
- 이미 해제된 메모리를 또 다시 해제하는 버그
- 이 또한 오류를 일으킬 수 있다.
좋은 점은 봤으니 안좋은 점은..
- 어떤 메모리를 해제할지 결정하는 데 비용이 든다. 객체가 필요없어지는 시점을 프로그래머가 미리 알고 있는 경우에도 GC 알고리즘이 메모리 해제 시점을 추적해야 하므로, 이 작업은 오버헤드(처리 시간, 메모리가 소비)가 된다.
- GC이 일어나는 타이밍이나 점유 시간을 미리 예측하기 어렵다. 때문에 프로그램이 예측 불가능하게 일시적으로 정지할 수 있다.
- 할당된 메모리가 해제되는 시점을 알 수 없다.
GC Algorithm
대표적인 알고리즘 두가지
- Reference Counting
- 참조 횟수 계산 방식
- Root Space - 스택 변수, 전역 변수 등 Heap 영역 참조를 담은 변수
- Heap 영역에 선언된 객체들에 참조 횟수를 기억하고 이 횟수가 0이 되면 해당 객체를 해제하는 방식
- 순환 참조의 경우 횟수가 1로 유지되는 문제가 있다.

한계점
- Mark And Sweep
- 포인터 추적 방식
- Root와 연결된 객체들(Marked)은 두고 연결이 끊어진 객체들을 지우는 방식(sweep)
- 객체가 가르키는 영역을 “사용중”으로 표시하고 그 객체가 가리키는 객체도 사용중으로 표시하면 접근 불가능한 메모리를 정리할 수 있다.
- 순환 참조의 문제 해결!
- 어떤 메모리를 언제 해제할지에 대해 수동으로 결정하는 것이 편할 때가 있다.
- 수동으로 메모리를 해제하고 싶다면 객체 메모리가 unreachable 상태로 명시하는 기능이 있어야 한다.
- 2019년 현재의 JavaScript에서는 명시적으로 또는 프로그래밍 방식으로 가비지 컬렉션을 작동할 수 없습니다.
- 최적화 기법
- generational collection(세대별 수집)
- incremental collection(점진적 수집)
- idle-time collection(유휴 시간 수집)

또 다른 한계점
JavaScript GC
위에서 설명한 바와 같이 자바스크립트는 자동으로 메모리를 할당하고 해제합니다.
const n = 123; // allocates memory for a number const s = "azerty"; // allocates memory for a string function f(a) { return a + 2; } // allocates a function (which is a callable object)
Javascript는 엔진 내의 가비지 컬렉터(Garbage Colloector)에서 메모리 관리를 수행한다.
GC의 기준은 도달 가능성(Reachability)에 따라서 메모리 관리를 수행한다.
어떤 알고리즘을 사용할까?
- 인터넷 익스플로러 6, 7 은 DOM 오브젝트에 대해 Reference counting 알고리즘으로 GC를 수행했었다.
- 현재 엔진은 Mark And Sweep 알고리즘을 사용한다. (IE, Firefox, Opera, Chrome, Safari)
도달할 수 없는 섬(Unreachable Island)

결론
- 수동으로 메모리를 해제할 수 있지만 우리는 신경 쓸 필요가 없을 것 같다.
- 자바스크립트에서는 V8 엔진의 GC를 통해 메모리를 관리한다.
- 이 또한 자동으로 관리되기에 이를 억지로 실행하거나 막을 수 없다.
- 도달 가능성을 기준으로 유지, 해제 (Mark and Sweep) 알고리즘
참조
구글 크롬 v8엔진 사용..?