JS/[web] 코어 JS 튜토리얼

[코어 JS] 4.3 - 객체: 가비지 컬렉션

web_seul 2021. 10. 3. 22:39
반응형

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

- 객체는 도달가능한 상태일 때 메모리에 남음

- 참조여부와 무관하게 서로 연결된 객체들도 도달 불가능할 수 있음

반응형