November 08, 2021
자바스크립트는 C언어 같은 로우 레벨 언어에서 malloc()과 free()를 이용해 직접 메모리 관리를 하는 것과 다르게 자동 메모리 관리 기법인 가비지 컬렉션
을 사용한다.
가비지 컬렉터
가 객체를 계속 감독하고, 더 이상 필요 없어진 객체의 메모리를 회수한다. 하지만 필요 없는 메모리를 항상 회수한다고 기대할 수는 없으므로 완전하다고 할 수는 없다. 오히려 예상치 못한 메모리 누수 혹은 에러를 마주할 수도 있다. 따라서 개발자는 가비지 컬렉션 기법을 사용하는 자바스크립트에서도 메모리 관리를 신경써야 한다.
여기서 2번은 개발자가 직접 코드를 짜면서 수행하게 된다. 그러나 1번과 3번, 메모리의 할당과 해제는 하이 레벨 언어인 자바스크립트에서는 자동으로 처리해준다.
대부분의 메모리 문제는 메모리 해제가 잘 되지 않아 발생한다.
가비지 컬렉터의 목적은 메모리 할당을 추적하고 할당된 메모리 블록이 더 이상 필요하지 않은 때를 판단하여 회수하는 것이다.
가비지 컬렉션이 할당된 메모리 블록이 더 이상 필요하지 않은지 판단하는 핵심 개념은 참조이다. 즉, 더 이상 “참조하지 않는다”고 판단하면 그 메모리 블록을 회수하는 것이다. “참조하지 않는다”고 판단하는 기준이 여러 가지가 있다. 다음은 MDN에서 설명하는 2개의 알고리즘이다.
여기서 말하는 “객체”는 자바스크립트의 객체뿐만 아니라 함수 스코프 혹은 전역 렉시컬 스코프까지 포함하는 개념이다.
이 알고리즘은 어떤 다른 객체에서도 참조하지 않는 객체를 더 이상 필요하지 않은 메모리로 판단하여 메모리를 해제한다.
그러나 이 경우, 순환 참조 시 메모리 해제가 일어나지 않아 메모리 누수가 발생한다.
이 알고리즘은 더 이상 접근할 수 없는 객체를 더 이상 필요하지 않은 메모리로 판단하여 메모리를 해제한다.
roots라 불리는 객체의 집합을 가정한다. 자바스크립트에서는 전역 객체가 root이다. 주기적으로 가비지 컬렉터는 루트부터 시작하여 루트가 참조하는 객체를 확인하고, 또 그 객체가 참조하는 객체를 확인하면서 접근할 수 있는 객체와 접근할 수 없는 객체를 찾는다.
이 경우 순환 참조 시에도 메모리 해제가 일어나며, 현재까지 모든 최신 브라우저에서는 이 알고리즘을 사용하고 있다.
그러나 모든 문제가 해결된 것은 아니다.
이 외에도 분리된 DOM 노드, 콘솔 출력 등의 여러 가지 이유로 메모리 누수가 발생할 수 있다.