📌 References
https://ko.javascript.info/garbage-collection
https://velog.io/@ono212/JS-GarbageCollection
Unmanaged, Low-level, Assembly Languages (C...)
개발자가 직접 메모리 관리를 해주어야 한다. 최적화를 잘 한다면 최고의 성능을 얻을 수 있지만 제대로 하지 않으면 치명적인 오류가 발생할 수 있다.
Managed, High-level Languages (Javascript...)
언어 차원에서 자동으로 메모리를 관리해주며 개발자는 접근이 불가능하다. 개발자가 메모리에 대해 신경쓸 필요가 없어 개발 생산성이 향상된다.
(특히 최근에는 하드웨어 성능이 빠르게 발전하고 있기 때문에, 최적화를 덜 고민하면서 개발생산성에 집중하기 좋다.)
✔️ 가비지 (Garbage)
더 이상 사용하지 않는(유효하지 않은) 메모리
✔️ 가비지 컬렉션 (Garbage Collection)
더 이상 사용하지 않는 메모리를 자동으로 정리하는 것 (개발자가 직접 관리할 필요가 없다.)
각 객체를 참조하는 변수의 수를 추적하는 방식으로 레퍼런스 카운트가 0이 되면 해당 객체와 관련된 메모리를 비운다. 순환 참조인 경우 가비지로 인식하지 못한다는 단점이 있다.
function func() {
let x = {};
let y = {};
x.a = y; //x는 y를 참조한다
y.a = x; //y는 x를 참조한다
}
func();
func 함수의 호출이 끝나면 내부 요소들을 더이상 사용하지 않으므로 메모리가 해제되어야 하지만, 서로 참조하고 있기 때문에 가비지로 인식되지 못해 메모리 낭비가 생긴다.
레퍼런스 카운팅 방식의 한계(순환참조)를 극복한 알고리즘이다.
각 객체에 in-use flag를 두고, 가비지 컬렉션 사이클마다 메모리 관리자가 모든 객체를 추적해서 flag에 표시(mark) 후 표시되지 않은 객체를 삭제(sweep)하는 방식이다. 어떤 객체와 연결되어 있더라도 루트에서 떨어져 있는 객체들은 가비지로 인식하여 레퍼런스 카운트 방식의 순환참조 문제를 해결할 수 있다.
자바스크립트 엔진은 어떻게 필요없는 것을 찾아내 삭제할까?
❗️ 도달 가능한 (reachable) 값
어떻게든 접근하거나 사용할 수 있는 값으로, 도달 가능한 값은 메모리에서 삭제되지 않는다.
루트 (root) : 태생부터 도달 가능하기 때문에, 명백한 이유 없이 삭제되지 않는다.
- 현재 함수의 지역 변수와 매개변수
- 중첩 함수의 체인에 있는 함수에서 사용되는 변수와 매개변수
- 전역변수
루트가 참조하는 값이나 체이닝으로 루트에서 참조할 수 있는 값
자바스크립트 엔진 내에서 가비지 컬렉터가 자동으로 끊임없이 동작하며 모든 객체를 모니터링하고 도달할 수 없는 객체는 삭제한다. 주의할 점은 참조된다고 해서 도달 가능한 것은 아니다. (도달할 수 없는 섬!)