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
위에서 설명한 바와 같이 자바스크립트는 자동으로 메모리를 할당하고 해제합니다.
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엔진 사용..?