undefined 타입의 값은 undefined이다. 할당하지 않은 변수는 undefined 값을 가진다. 이 것은 확보된 메모리 공간을 비어있던 기존에 사용했던 Garbage value가 들어있던 자바스크립트 엔진이 undefined로 초기화하기 때문이다.
이것은 자바스크립트 엔진이 초기화 하는 것이기 때문에 개발자의 의도와 구분되지 않는다. 변수에 값이 없다는 것을 명시하고 싶을 때는 undefined를 할당하지 않고 null을 할당하면 의도를 나타낼 수 있다.
null 타입의 값은 null이 유일하다. null의 타입은 object이다. 이 부분은 설계 오류다. 원래는 type이 null이어야 한다. 이 부분은 고치면 많은 문제가 생길 수 있는 부분이 있기 때문에 null로 두는 부분이 있다고한다.
null은 프로그래밍 언어에서 의도적으로 변수에 값이 없다는 것을 명시할 때 사용한다. 변수가 기억하는 참조정보를 제거하는 것을 의미한다. 이렇게 null이 되면 가리키지 않는 참조 값의 메모리 영역은 가비지 콜렉션을 수행하게 된다.
가비지 콜렉션 알고리즘의 핵심 개념은 참조이다. A라는 메모리를 통해 (명시적이든 암시적이든) B라는 메모리에 접근할 수 있다면 "B는 A에 참조된다" 라고 한다. 예를 들어 모든 자바스크립트 오브젝트는 prototype 을 암시적으로 참조하고 그 오브젝트의 속성을 명시적으로 참조한다.
아무도 참조하지 않는지 카운팅하는 알고리즘으로 가비지 콜렉션을 수행한다. 하나의 오브젝트라도 참조하고 있다면 해당 오브젝트는 가비지 콜게션을 수행하지 않는다.
let codestates = {
full: {
im29 : 26,
im30 : 80
}
}
let code = codestates;
codestates = 'bye';
let fullTime = code.full;
code = 'bye';
fullTime = null;
두 객체가 서로 참조하는 속성으로 순환구조를 이루는 경우 호출이 완료된 후에는 두 객체는 스코프를 벗어나게 될 것이며 사용되지 않기 때문에 메모리에 회수되어야 한다. 그러나 계속 서로를 참조하고 있기 때문에 가비지 컬렉션 대상이 되지 않게 된다. 이렇게 서로 참조하는 경우에 확보가 되지 못하는 메모리가 생겨 메모리 누수의 원인이되기도 한다.
var div;
window.onload = function() {
div = document.getElementById('myDivElement');
div.circularReference = div;
div.lotsOfData = new Array(10000).join('*');
};
"더이상 필요없는 오브젝트"
를 "닿을 수 없는 오브젝트"
로 정의한다.
roots라는 집합을 가지고 있다. 자바스크립트는 전역변수와 같다. 주기적으로 roots로부터 시작해서 roots가 참조하는 오브젝트들로 탐색해서 닿을 수 있는지 즉 연결되어있는지를 주기적으로 가비지 콜렉션을 수행한다.
Reference-Counting 보다 효율적이다. 참조되지 않는 오브젝트는 모두 닿을 수 없는 오브젝트이지만 역은 성립하지 않기 때문이다. 이 부분으로 순환참조를 해결 할 수 있다.
2012년 이후로 mark-and-sweep을 사용하다고 한다. 지속적인 개선중에 있는 알고리즘도 이 알고리즘으로 정의하고 있다.
수동으로 결정하는 것이 편리할 때가 있지만 주기적으로 가비지 콜렉션이 수행되지 건에는 메모리 해제가 되지 않는 점이 한계점이다.