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