보통 프로그래밍 언어에서 메모리 생명 주기를 말하면 다음과 같다.
1. 필요한 메모리 할당
2. 할당된 메모리 사용 (읽기, 쓰기)
3. 해당 메모리가 필요 없어지면 해제
자바스크립트에서는 값 초기화, 함수호출 시에 메모리가 할당되고,
할당된 메모리가 더 이상 필요하지 않은 시점에 메모리를 해제한다.
C, C++ 처럼 로우레벨 언어들은 수동으로 메모리를 직접해제 해주어야하지만, 자바스크립트나 파이썬과 같이 하이 레벨언어는
GC (가비지 컬렉션)이라는 자동 메모리 관리 형식을 활용한다.
가비지 컬렉터의 목적은 메모리 할당을 모니터링하고, 할당된 메모리의 블록이 더 이상 필요하지 않은 시점을 확인하여 회수하는 것이다.
하지만, 항상 필요 없어진 메모리만을 해제한다고 확신은 할 수 없기 때문에, 안전하지만 완전하지 못한 기술이라고도 부른다.
그럼 가비지 컬렉터는 어떻게 동작하는 걸까?
1. 참조 - 세기 (Reference-counting) 알고리즘
: 더 이상 필요없는 객체 === 어떤 다른 객체도 참조하지 않는 객체로 정의.
특정 객체를 참조하는 객체가 하나도 없다면, 그 객체에 대해 GC를 수행한다.
우리가 알고있는 개념과 같지만, "순환 참조"에 대해 방어 할 수 없다.
function f(){
var x = {};
var y = {};
x.a = y;
y.a = x;
}
위 코드는 x,y객체가 서로 순환 참조하고 있어서 GC가 수행되지 않는다.
2. Mark-and-sweep 알고리즘
: 더 이상 필요없는 객체 === 닿을 수 없는 객체로 정의.
무엇인가에 표시(mark)하고 치우는(sweep) 알고리즘이다.
이 알고리즘은 roots라는 객체의 집합을 가진다. (js에서는 전역변수들)
주기적으로 GC는 roots로 시작하여 roots가 참조하는 객체들, roots가 참조하는 객체가 참조하는 객체들을 접근할 수 있는 객체라고 mark한다.
그 후에, 접근할 수 없는 객체에 대해 GC를 수행한다.
2012년 기준 모든 최신 브라우저들이 GC에서 mark-and-sweep 알고리즘을 사용한다고 한다.
(다른 알고리즘들도 있는데, 모두 mark-and-sweep 알고리즘을 확장한 개념이라고 한다.)
다시 위 순환참조 알고리즘을 보면,
function f가 종료되고 나면, 전역 변수들에서 x,y에 담긴 객체들에 접근할 수 있는 방법이 없기 때문에, 두 객체에 대해 GC가 수행되어 순환참조 문제를 해결할 수 있다.
세부적인 단계는 다음 2단계이다.
1. Mark 단계
: 객체가 생성될 때마다, mark bit를 0으로 설정
: Mark 단계에서 모든 접근 가능한 객체의 mark bit를 1로 설정
2. Sweep 단계
: Mark 단계 후에 mark bit가 여전히 0인 객체들에 대해서, 도달할 수 없는 객체라고 판단하여 GC를 수행한다.
'개발 > FrontEnd Interview' 카테고리의 다른 글
em? rem? (2) | 2021.04.05 |
---|---|
모듈, 라이브러리 차이 (0) | 2021.04.05 |
SPA에서 SSR를 사용할 수 있을까? (0) | 2021.04.04 |
CSR, SSR, SPA, MPA 총 정리 (0) | 2021.04.04 |
css !important에서 !의 유래 (0) | 2021.04.04 |