4.3 가비지 컬렉션
눈에 보이지 않는 곳에서 메모리 관리를 수행하는 JS가 쓸모없어진 메모리를 처리하는 방법
- 가비지 컬렉션 기준
JS는 도달가능성(reachability- 어떻게든 접근하거나 사용할 수 있는 값) 개념을 사용헤 메모리 관리를 수행
1. 태생부터 도달 가능하여 명백한 이유없이 삭제되지 않는 값
ex) 루트(root) - 현재 함수의 지역 변수와 매개변수 중첩 함수의 체인에 있는 함수에서 사용되는 변수와 매개변수, 전역 변수 등
2. 루트가 참조하는 값, 체이닝으로 루트에서 참조할 수 있는 값은 도달 가능한 값이 됨
ex) 전역 변수에 객체가 저장되어 있을 때, 해당 객체의 프로퍼티가 또 다른 객체를 참조할 경우 프로퍼티가 참조하는 객체는 도달 가능한 값이 됨, 객체가 참조하는 다른 모든 것들도 도달 가능하다고 여겨짐
자바스크립트 엔진 내에서는 모든 객체를 모니터링하고 도달할 수 없는 객체는 삭제하는 가비지 컬렉터(garbage collector)가 끊임없이 동작함
- 간단한 예시
// user엔 객체 참조 값이 저장됩니다.
let user = {
name: "John"
};
//(global)user은 {name: "John"}이라는 객체를 참조
//(global)user -> (Object){name: "John"}
//user를 다른값으로 덮어쓰면 참조가 사라짐
user = null;
//John은 도달할 수 없는 상태가 되어 메모리에서 삭제됨 = 가비지 컬렉터o
//(global)user -x- (Object){name: "John"}
- 참조 두개
// user엔 객체 참조 값이 저장됩니다.
let user = {
name: "John"
};
let admin = user;
//(global)user -> (Object){name: "John"}
//(global)admin -> (Object){name: "John"}
user = null;
//user의 참조값은 사라지지만 admin의 참조값은 사라지지않음 = 가비지 컬렉터x
//(global)user -x- (Object){name: "John"}
//(global)admin -> (Object){name: "John"}
- 연결된 객체
function marry(man, woman) {
woman.husband = man;
man.wife = woman;
return {
father: man,
mother: woman
}
}
//marry는 매개변수로 받은 두 객체를 '서로 참조'해서 결혼시키고
//두 객체를 포함하는 '새로운 객체 반환'
let family = marry({
name: "John"
}, {
name: "Ann"
});
//(global)family -> (Object) -> father -> (Object){name : "John"}
// wife ↓ ↑ husband
//(global)family -> (Object) -> mother -> (Object){name : "Ann"}
delete family.father;
delete family.mother.husband;
//(global)family -> (Object) -> father -x- (Object){name : "John"}
// wife ↓ ↑ x husband
//(global)family -> (Object) -> mother -> (Object){name : "Ann"}
//John으로 도달하는 참조가 모두 해제됨, 외부로 나가는 참조는 영향x
//(Object){name : "John"} 삭제
//(global)family -> (Object) -> mother -> (Object){name : "Ann"}
???질문 중간의 Object의 역할
- 도달할 수 없는 섬
family = null;
//(global)family -x- (Object) -> father -> (Object){name : "John"}
// wife ↓ ↑ husband
//(global)family -x- (Object) -> mother -> (Object){name : "Ann"}
: John과 Ann은 서로를 참조하지만 family객체와 루트의 연결이 사라지면서 루트 객체를 참조하는 것이 없어짐
- 내부 알고리즘
가비지 컬렉션의 기본 알고리즘'make-and-sweep'
가비지 컬렉션의 단계
루트(root)정보 수집, 'mark(기억)' -> 루트가 참조하는 모든 객체를 방문, 'mark' -> mark된 모든 객체에 방문, 해당 객체가 참조하는 객체도 mark (한번 방문한 객체는 모두 mark하기 때문에 재방문x) -> 루트에서 도달 가능한 모든 객체를 방문할 때까지 과정 반복 -> mark되지않은 모든 객체를 메모리에서 삭제
가비지 컬렉션을 더 빠르게 하는 최적화 기법
- generational collection(세대별 수집)
: 객체를 '새로운 객체'와 '오래된 객체'로 나눔,
상당수의 객체는 생성 후 역할을 수행하면 쓸모x -> '새로운 객체'로 구분하여 가비지 컬렉터가 공격적으로 메모리에서 제거
일정시간이상 살아남은 객체는 '오래된 객체'로 분류하여 덜 감시하게 됨
- incremental collection(점진적 수집)
: 가비지 컬렉션을 여러 부분으로 분리하여 별도로 수행
- idle-time collection(유휴 시간 수집)
: 실행에 주는 영향 최소화를 위해 CPU가 유휴 상태일 때 가비지 컬렉션 실행
요약
- 가비지 컬렉션은 엔진이 자동으로 수행하므로 개발자는 컨트롤x
- 객체는 도달가능한 상태일 때 메모리에 남음
- 참조여부와 무관하게 서로 연결된 객체들도 도달 불가능할 수 있음
'JS > [web] 코어 JS 튜토리얼' 카테고리의 다른 글
[코어 JS] 4.5 - 객체: new 연산자와 생성자 함수 (0) | 2021.10.11 |
---|---|
[코어 JS] 4.4 - 객체: 메서드와 this (0) | 2021.10.04 |
[코어 JS] 4.2 - 객체: 참조에 의한 객체 복사 (0) | 2021.10.03 |
[코어 JS] 4.1 - 객체: 기본 (0) | 2021.10.03 |
[코어 JS] 3 - 코드 품질 (0) | 2021.09.27 |