자바스크립트의 메모리 관리에 대해서 아는대로 설명해주세요.
분야: 프론트엔드
메모리 관리를 크게 메모리 할당과 해제 두 가지 과정으로 나누어 설명드리겠습니다. C와 같은 저수준 언어에서는 malloc(), free()와 같은 함수를 통해 개발자가 직접 메모리를 할당하고 해제합니다. 하지만 자바스크립트에서는 이러한 작업이 언어 차원에서 자동으로 이루어집니다.
메모리 할당과 해제에 대해 차례로 설명드리겠습니다.
메모리 할당
메모리 할당은 변수나 객체를 생성할 때 발생합니다. 예를 들어, const name = "maeil-mail"; 와 같은 코드에서 name 변수는 메모리에 할당됩니다.
문자열, 숫자와 같은 원시 값은 Stack 영역에 저장됩니다. 원시 값은 고정 크기를 가지기 때문에 엔진이 컴파일 타임에 그 크기를 알고 있어 정적 데이터라고 불립니다.
한편, 객체(참조 타입)는 Heap 영역에 저장됩니다. 객체는 실행 시점에 필요한 만큼 메모리가 동적으로 할당되기 때문에 동적 데이터라고 불립니다.
메모리 해제
메모리 해제는 할당된 메모리가 더 이상 필요없을 때 발생합니다. 자바스크립트는 가비지 컬렉션(GC) 이라는 자동 메모리 해제 방법을 사용합니다. 언어 차원에서 메모리 할당을 추적하고, 특정 메모리가 필요하지 않게 되었다면 메모리를 해제하는 방식입니다.
대표적인 가비지 컬렉션 알고리즘인 Reference-counting과 Mark-and-sweep에 대해 간단히 설명드리겠습니다.
Reference-counting는 단순하게 구현된 알고리즘으로, 객체가 참조되는 횟수를 추적하고 참조 횟수가 0이 되면 메모리에서 해제합니다. 즉, 다른 어떤 객체도 참조하지 않는 객체를 찾아내어 메모리를 해제하는 방식입니다. 하지만 이 방식에서는 순환 참조가 발생할 경우, 참조 카운트가 0이 되지 않아 메모리에서 해제되지 않는 문제가 발생하는 한계점이 있습니다.
Mark-and-sweep은 루트 객체에서 시작하여 참조되는 객체를 표시(mark)하고, 마지막까지 표시되지 않은 객체를 찾아 메모리를 청소(sweep), 즉 해제하는 방식입니다. 이 방식에서는 순환 참조가 발생하더라도 루트에서 도달이 불가능하다면 표시가 되지 않습니다. 이런 특징으로 인해 Reference-counting 방식의 한계점을 보완할 수 있습니다.