가비지 컬렉션은 프로그램에서 더 이상 사용하지 않는 메모리를 자동으로 정리하는 것입니다. 이 기능을 가진 언어(혹은 엔진)는 자바, C#, 자바스크립트 등이 있습니다.
자바스크립트는 보이지 않는 곳에서 메모리를 관리합니다.
더 이상 사용하지 않는 메모리를 판단하는 기준은 도달 가능성(Reachability)
입니다.
도달 가능하다는(Reachable)
값은 어떻게든 접근하거나 사용할 수 있는 값입니다. 이 값은 메모리에서 삭제되지 않습니다.
예를 들어, 자바스크립트로 어떤 함수를 만들었습니다.
let output = {
name: "Bar",
};
function foo(a) {
output.name = a;
}
foo("Kim");
console.log(output); // {name: "Kim"}
여기서, 전역 변수는 output
입니다. 함수 foo
의 지역변수는 output.name
, 전달된 매개변수는 "Kim"
입니다.
이 값들을 루트(root)
라고 부릅니다.
전역 변수에 객체가 저장되어 있고, 이 객체의 프로퍼티가 참조하는 객체는 도달 가능한 값입니다. 이 객체가 참조하는 다른 모든 것들도 도달 가능합니다.
전역 변수 output
은 {name: "Bar"}
이라는 객체를 참조합니다.
만약 여기서, output
의 값을 다른 값으로 덮어쓴다면 참조하는 객체는 사라집니다.
output = null;
기존에 output
이 참조하던 객체는 null
이 덮어쓰면서 참조할 수 없게됐습니다.
참조할 수 없게 되어, foo
함수도 실행하게되면 다음과 같은 에러를 가져옵니다.
기존에 참조하던 객체 {name: "Bar"}
는 이제 도달할 수 없는 상태가 되었습니다. 접근할 방법도 참조하는 것도 없습니다. 자바스크립트 가비지 컬렉터는 이 객체를 삭제하고, 또한 메모리에서도 삭제하게 됩니다.
자바스크립트 엔진 내에선 가비지 컬렉터가 끊임없이 동작하고 있으며, 가비지 컬렉터는 모든 객체를 탐색하고, 도달할 수 없는 객체는 삭제합니다.
위 과정은 다음과 같습니다.
가비지 컬렉터는 위에 나열된 루트
정보를 수집하고 이를 마킹합니다.
루트가 참조하는 모든 객체를 확인하고, 이를 마킹합니다.
마킹된 객체에 방문하고, 그 객체들이 참조하는 객체도 마킹합니다.
도달 가능한 모든 객체를 방문할 때까지 반복합니다.
마킹되지 않은 모든 객체를 메모리에서 삭제합니다.
자바스크립트 엔진은 가비지 컬렉터가 끊임없이 돌아가는데, 실행에 영향을 미치지 않으며 가비지 컬렉션을 더 빠르게 하는 다양한 최적화 기법을 적용했습니다.
세대별 수집(Generational Collection)
새로운 객체
와 오래된 객체
로 나누고, 객체가 생성되고 그 역할을 수행하고 더이상 쓰이지 않는 경우 자바스크립트는 이 객체를 새로운 객체
로 분류합니다. 가비지 컬렉터는 이 새로운 객체
를 적극적으로 메모리에서 제거합니다.점진적 수집(Incremental Collection)
유휴 시간 수집(Idle-time Collection)
이 외에도 여러가지 가비지 컬렉션 최적화 기법이 있습니다.
요약하자면 다음과 같습니다.
가비지 컬렉션은 엔진이 자동으로 수행합니다. 개발자는 이를 억지로 실행하거나 막을 수 없습니다.
객체는 도달 가능한 상태일 때 메모리에 남습니다.
참조가 가능하다고 해서 도달 가능한 것은 아닙니다. (더 공부해야할 내용)
가비지 컬렉션에 대해 조금 더 깊게 공부해야할 것 같습니다. 간단하게 가비지 컬렉션에 대해 개요만 짧게 기록해보았습니다.
모던 자바스크립트 튜토리얼 을 참고하여 작성했습니다.