[모던자바스크립트] 24. 가비지 컬렉션
in Devlog on JavaScript
이 글은 번역 및 정리 글입니다. 출처: javascript.info
가비지 컬렉션
자바스크립트의 메모리 관리는 잘 보이지 않는다. 우리는 많은 변수, 객체, 함수등을 만든다. 더 이상 필요하지 않을경우는 어떻게 되는가? 자바스크립트엔진이 어떻게 그것을 발견하고 정리하는가?
접근성
자바스크립트에서 메모리 관리의 핵심 개념은 접근성
이다.
간단히 말해, 도달 가능한 값은 어떻게든 액세스하거나 사용할 수 있는 값이다. 이러한 도달 가능한 값들은 메모리에 저장되도록 보장된다.
도달 가능한 값의 기본 집합이 있다.
- 현재 기능의 지역 변수 및 매개 변수
- 현재 중첩 호출 체인의 다른 함수에 대한 변수 및 매개 변수
- 글로벌 변수
- (…다른 내부적 요인들)
이러한 값들을 루트(근)
이라고 한다.
다른 값은 참조 또는 참조 체인에 의해 루트에서 도달 할 수 있는 경우 도달가능한 것으로 간주된다.
예를 들어 로컬변수에 객체가 있고 해당 객체에 다른 객체를 참조하는 속정이 있는 경우 해당 객체는 도달 가능한 것으로 간주된다. 그리고 그것이 참조하는 것들도 도달할 수 있다.
자바스크립트엔진에는 가비지 컬렉터
라고하는 백그라운드 프로세스가 있다. 모든 개체를 모니터링하고 연결할 수 없는 개체를 제거한다.
간단한 예
let user = {
name: "John"
};
이때 user
는 {name: "John"}
라는 객체의 참조를 가지고 있다. 하지만 user
를 덮어쓰면 어떻게 될까?
user = null;
이제 {name: "John"}
객체에는 도달할 수 없게된다. 접근 가능한 방법이나 참조가 없다. 가비지 콜렉터는 데이터를 폐기하고 메모리를 해제시킨다.
두 참조
유저가 객체를 가진 상태에서 admin
에 복사되었다고 해보자.
let user = {
name: "John"
};
let admin = user;
이전처럼 유저의 참조를 풀어보자.
user = null;
이제는 admin
으로 객체에 접근할 수 있기때문에 여전히 객체는 남아있다.
상호 연결된 객체
function marry(man, woman) {
woman.husband = man;
man.wife = woman;
return {
father: man,
mother: woman
};
}
let family = marry(
{
name: "John"
},
{
name: "Ann"
}
);
함수 marry
는 서로에 대한 참조를 제공하여 두 객체를 결혼시키고 두 객체를 모두 포함하는 새 객체를 반환한다.
두개의 참조를 제거해보자
delete family.father;
delete family.mother.husband;
여전히 모든 객체에 선이 있지만, John
에게 도달하는 선은 없고 나가는건만 있는걸 알 수 있다.
발신참조는 중요하지 않기때문에 John
은 도달할 수 없다고 판단되어 메모리에서 제거된다.
고립된 섬
상호 연결된 객체가 어딘가에서 도달할 수 없다면 메모리에서 제거된다.
이전의 소스에서 하나만 바꿔보자.
family = null;
끊어진 객체는 제거된다.
내부 알고리즘
기본 가비지 수집 알고리즘을 마크 앤 스윕
이라고 한다. 다음의 단계들이 정기적으로 수행된다.
- 가비지 컬렉터는
루트
를 가져와서마크(기억)
한다. - 모든 참조를 방문하고
마크
한다. - 마크된 객체를 방문하여 해당 참조를 마크한다. 만문한 모든 객체는 추후 동일한 객체를 두번 방문하지 않도록 기억된다.
- 모든 도달 가능한 참조가 방문될 때까지 계속된다.
- 마크된것을 제외한 모든 객체가 제거된다.
그외 몇가지 최적화 알고리즘이 있다.
- 세대 별 수집: 개체는
새로운 것
과오래된 것
의 두 세트로 나뉜다. 많은 객체들이 나타나서, 할 일을 하고, 금장 죽는다. 이러한 것들은 청소되기 쉽다. 오래 살아남은 객체들은 덜 검사 받는다. - 증분 수집: 많은 객체가 있고 전체 객체 세트를 한 번에 들러서 마크하려면 시간이 걸리고 실행이 지연될 수 있다. 그로인해 엔진은 가비지 컬렉션을 여러 조각으로 나누려고한다. 그런 다음 조각이 하나씩 실행된다. 변경 사항을 추적하려면 추가 예약이 필요하지만 큰 지연 대신 작은 지연이 여러개 있게 된다.
- 유휴 시간 수집: 가비지 컬렉터는 CPU가 유휴 상태일때만 실행을 시도하여 실제 작업에 미치는 영향을 줄인다.
2023년 새해에는 성장하고 함께하고 싶다면?
Pre A 단계 이상의 스타트업 C 레벨들이 모여서 커뮤니티를 만들었습니다. 같이 스터디하고 친해질 일잘러를 찾습니다.