가비지 컬렉터
가비지 컬렉터은 자동 메모리 관리 방법이다.
자바스크립트를 느슨(?)하게 생각할 경우, '훌륭하다. 귀찮지 않아서 좋다. 알아서 해주니까 신경안써도 되겠구나' 라고 생각할 수 있으나 그런 방심을 금물...(시간이 비용인 세상이다)
이전 글에서 가비지 컬렉터가 무슨일을 하는지 알아보았다.
그러면 가비지 컬렉터는 언제, 어떤 방식으로 일을 할까?
언제라는 질문에 대한 답은 '없다' 이다. 자동으로 동작하기 때문에 강제로 멈추거나 실행을 시키는 것도 불가능하다.(..ㅠ)
자바스크립트 엔진 내에서 끊임없이 동작합니다. 가비지 컬렉터는 모든 객체를 모니터링하고, 도달할 수 없는 객체는 삭제합니다.
그럼 어떤 방식으로 일하는지 알아볼 필요가 있다.
1. Reference-counting ( 참조 숫자세기 )
아무것도 참조하지 않으면 가비지에 수집합니다.
한계 : 순환참조
2. Mark and Sweep ( 표시하고 쓸어담기 )
도달할 수 없는 객체를 가비지로 정의하고, 도달할 수 있는 객체는 표시를 한 후, 쓸어버린다.
여기서, 도달할 수 없는! 이라는 것이 조금 애매하다고 느껴진다면 다음을 보자.
태생부터 도달 가능한 값들은 아래와 같다.
1. 현재 함수의 지역 변수와 매개변수
2. 중첩 함수의 체인에 있는 함수에서 사용되는 변수와 매개변수
3. 전역 변수
4. 기타
이런 값을 루트(root)라고 부른다.
(2012년부터는 모든 브라우저들인 Mark and Sweep 방식으로 가비지컬렉터를 사용한다고 합니다.)
위의 reference-counting의 문제점으로는 불필요한 값임에도 불구하고 어디에선가 참조가 걸려있다면 이에 대한 메모리를 해제하지 않는다는 문제점이 있었다. 반면에 Mark-and-sweep 알고리즘은 이 값이 참조되고 있는 값인지에 중점을 두지않고 도달가능성(reachablility)에 중점을 둔다.
도달 가능성이란 자바스크립트의 root라는 글로벌 object에서부터 시작하여 참조되는가에 대한 여부이다. 다시말해 root에서 부터 해당 값까지 도달이 가능한가에 대한 여부이다.
따라서 어떤 값에 대한 참조가 없는 경우는 당연히 도달이 불가능하기 때문에 메모리가 해제되어야 하는 값으로 여겨지고, 참조 되고 있다고 하더라도 root로부터 도달할수 없다고 여겨진다면 처리된다.