[JS] 가비지 컬렉션

/:frontend

자바스크립트는 메모리 관리를 수행한다. 만들어 놓은 값들 중 더이상 사용하지 않는 것들을 가비지 콜렉터를 통해 찾아내 삭제한다.

가비지 컬렉션 기준

'도달 가능성(reachability)' 개념을 사용해 메모리를 관리한다.

'도달 가능성'이란 어떻게든 접근하거나 사용할 수 있는 값을 의미한다.

도달 가능한 값은 root부터 시작해서 root가 참조하는 객체들, roots가 참조하는 객체가 참조하는 객체들, 그리고 이게 쭉 이어져서 닿울 수 있는 객체를 뜻한다. Root는 태생부터 도달 가능한 값들을 뜻하는데, 아래와 같다.

  • 전역변수
  • 현재 함수의 지역변수와 매개변수
  • 중첩 함수의 체인이 있는 상태에서 사용되는 변수와 매개변수
  • 기타 등등

자바스크립트의 가비지 컬렉터는 끊임없이 동작하면서 모든 객체를 모니터링하고, 도달할 수 없는 객체를 삭제한다.

내부 알고리즘 'Mark-and-sweep'

가비지 컬렉션은 대개 다음 단계를 거처 수행된다.

  1. Root 정보를 수집하고 이를 'mark(저장)'한다.

  2. Root가 참조하고 있는 모든 객체를 방문하고 이를 'mark'한다.

  3. 'mark'된 모든 객체에 방문하고 그 객체들이 참조하는 객체도 'mark'한다. Root에서 도달 가능한 모든 객체를 방문할 때까지 반복한다.

  4. 'mark'되지 않은 모든 객체를 삭제한다.

자바스크립트 엔진은 실행에 영향을 미치지 않으면서 가비지 컬렉션을 더 빠르게 하는 최적화 기법을 적용한다.

  • Generational collection: 객체를 '새로운 객체'와 '오래된 객체'로 나눈다. 새로운 객체는 생성 이후 제 역할을 한 후 빨리 사라지는 경우가 많기 때문에 이런 객체를 공격적으로 메모리에서 제거한다.
  • Incremental collection: 가비지 컬렉션에 많은 리소스가 소모되는 것을 막기위해 가비지 컬렉션을 여러 부분으로 분리해 각각 별도로 수행한다.
  • Idle collection: CPU가 idle 상태일 때만 수행한다.

이외에도 다양한 기법과 알고리즘이 존재하지만 엔진마다 세부사항과 기법은 다르다.

참조