변수에 값을 재할당할 때 기존에 사용하고 있는 메모리 공간을 지우고 재할당하는 게 아니라 새로운 메모리 공간을 확보해서 저장한다.
그렇다면 기존에 사용하던 메모리 공간은 어떻게 되는 것일까?
✅ 참고 : Managed Language & Unmanaged Language
C와 같은 언매니지드 언어는 개발자가 명시적으로 메모리를 할당하고 해제하기 위해 malloc()과 free() 같은 low-level 메모리 제어 기능을 제공한다. 언매니지드 언어는 메모리 제어를 개발자가 주도할 수 있으므로 개발자의 역량에 따라 최적의 성능을 확보할 수 있지만 그 반대의 경우 치명적 오류를 생산할 가능성도 있다.
Javascript 같은 매니지드 언어는 메모리의 할당 및 해제를 위한 메모리 관리 기능을 언어 차원에서 담당하고 개발자의 직접적인 메모리 제어를 허용하지 않는다. 즉, 개발자가 명시적으로 메모리를 할당하고 해제할 수 없다. 더 이상 사용하지 않는 메모리의 해제는 가비지 콜렉터가 수행하며, 이 또한 개발자가 관여할 수 없다. 매니지드 언어는 개발자의 역량에 의존하는 부분이 상대적으로 작아져 어느 정도 일정한 생산성을 확보할 수 있다는 장점이 있으나 성능 면에서 어느 정도의 손실은 감수할 수 밖에 없다.
할당된 메모리가 더 이상 필요 없을 것으로 추정되어 회수하는 것.
가비지 컬렉터가 자바스크립트 엔진에서 끊임없이 동작하며 객체를 모니터링한다.
var x = {
a: {
b: 1
}
};
var y = x.a;
var z = a.b;
y = null; // x는 가비지 컬렉션이 되지만 a는 여전히 참조되고 있다.
z = 2; // a 객체와 b 프로퍼티 모두 가비지 컬렉션이 된다.
객체에 참조가 하나도 없는 경우 가비지 컬렉션이 되는 방식이다.
function f () {
var x = {};
var y = {};
x.a = y; // x는 y를 참조한다.
y.a = x; // y는 x를 참조한다.
}
f();
스코프를 벗어난 쓸모없는 객체도 순환 참조로 인해 가비지 컬렉션이 되지 못하는 문제점이 있었다.
참조가 아닌 도달할 수 있는지를 기준으로 메모리를 정리한다.
root(전역 변수와 현재 함수의 변수)에서 접근할 수 있는 모든 객체를 mark(기억)하고, mark되지 않은 모든 객체는 가비지 컬렉션이 된다.
알고리즘이 메모리가 더 이상 필요하지 않을 정확한 시점을 알 수 없다고 했을때 Javascript 애플리케이션은 실제로 필요한 것보다 더 많은 메모리를 사용할 수 있다.
객체가 가비지가 표기(mark)되어도 할당된 메모리를 수집할 때를 정하는 것은 가비지 컬렉터가 결정한다.
애플리케이션이 가능한 한 메모리를 효율적으로 사용하려면 lower-level의 언어를 사용하는게 좋다.
가비지 컬렉트 알고리즘은 미사용된 객체를 정리하기 위해 주기적으로 실행된다.
문제는 개발자인 우리가 언제 일이 일어난지 정확히 모른다는 것이다. 많은 가비지를 수집하거나 자주 가비지를 수집하면 일정량의 계산 능력이 필요하므로 성능에 영향을 줄 수 있다.
하지만 이는 일반적으로 유저나 개발자에게 발견되기는 어렵다.