자바스크립트_기초_4.3

HwiJeongLee·2021년 9월 15일
0

자바스크립트

목록 보기
26/28

가비지 컬렉션

원시값, 객체, 함수 등 코드에 만든 모든 것은 메모리를 차지합니다.
자바스크립트 엔진은 이런 메모리를 관리해줍니다.

자바스크립트 엔진은 어떻게 필요 없는 것을 찾아내 삭제할까요??

가비지 컬렉션 기준

자바스크립트는 도달 가능성(reachability)라는 개념을 사용해 메모리를 관리합니다.

도달 가능한 값
어떻게든 접근하거나 사용할 수 있는 값으로 메모리에서 삭제되지 않습니다.

1

  • 현재 한수의 지역 변수와 매개변수
  • 중첩 함수의 체임에 있는 함수에서 사용되는 변수와 매개변수
  • 전역 변수

📌 이 값들은 태생부터 도달 가능하기 때문에 명백한 이유 없이는 삭제되지 않습니다. 이런 값은 root라고 합니다.

2

루트가 참조하는 값이나 체이닝으로 루트에서 참조할 수 있는 값은 도달가능한 값이 됩니다.

전역 변수에 객체가 저장되어있다고 가정해 봅시다. 이 객체의 프로퍼티가 또 다른 객체를 참조하고 있다면, 프로퍼티가 참조하는 객체는 도달 가능한 값이 됩니다. 또 이 객체가 참조하는 모든 것들도 도달 가능하다고 여겨집니다.

❗ 자바스크립트 엔진 내에선 가비지 컬렉터가 끊임없이 동작합니다.
❗ 가비지 컬렉터는 모든 객체를 모니터링하고, 도달할 수 없는 객체는 삭제합니다.

가비지 컬렉터 예시

let user = {
	name : "Jhon"
};

user에 객체 참조 값이 저장됩니다.

user = null

이제 user는 null이 되었으므로 위의 객체는 도달할 수 없는 상태가 되었습니다. 가비지 컬렉터는 저장된 데이터를 삭제하고, Jhon을 메모리에서 삭제합니다.

let user = {
  name: "John"
};

let admin = user;
user = null;

위 와 같은 상황은 user의 값을 다른 값으로 바꾸었지만 admin은 해당 객체를 가지고 있으므로 삭제할 수 없습니다. 만약 admin도 값을 덮어쓴다면 객체는 삭제될 수 있습니다.

연결된 객체

function marry(man, woman) {
  woman.husband = man;
  man.wife = woman;

  return {
    father: man,
    mother: woman
  }
}

let family = marry({
  name: "John"
}, {
  name: "Ann"
});

이렇게 되면 모든 객체가 도달 가능한 상태가 됩니다.

delete family.father;
delete family.mother.husband;

이렇게 위의 두개를 끊었다면 Jhon으로 들어오는 화살표가 모두 사라졌으므로 도달 가능한 상태에서 벗어납니다.

외부로 나가는 참조는 도달 가능한 상태에 영향을 주지 못합니다. 외부에서 들어오는 참조만이 도달 가능 상태에 영향을 줍니다.
Jhon은 이제 도달 가능한 상태가 아니므로 메모리에서 제거됩니다.

가비지 컬렉션 후에는 메모리 구조가 아래와 같이 바뀝니다.

도달할 수 없는 섬

function marry(man, woman) {
  woman.husband = man;
  man.wife = woman;

  return {
    father: man,
    mother: woman
  }
}

let family = marry({
  name: "John"
}, {
  name: "Ann"
});

family = null;

근원 객체가 family가 아무것도 참조하지 않도록 해봅시다.

내부 객체들끼리는 도달 가능하지만 family 객체와 루트의 연결이 사라지면서 덩어리 전체가 도달할 수 없게되고 객체 전부가 메모리에서 제거됩니다.

내부 알고리즘

mark-and-sweep 가비지 컬렉션 기본 알고리즘을 알아봅시다.

  1. 가비지 컬렉터는 루트 정보를 수집하고 mark(기억)합니다.

  2. 루트가 참조하고 있는 모든 객체를 방문하고 mark(기억)합니다.

  3. mark(기억)된 모든 객체에 방문하고 그 객체들이 참조하고 있는 객체도 mark(기억)합니다. 한번 방문한 객체는 전부 mark(기억)하므로 다시 방문할 필요 없습니다.

  4. 루트에 도달 가능하 모든 객체륿 방문할 때까지 위 과정을 반복합니다.

  5. mark(기억)되지 않은 모든 객체를 메모리에서 삭제합니다.

자바스크립트 엔진은 가비지 컬렉션을 더 빠르게 하는 다양한 최적화 기법을 적용합니다.

  • generational collection(세대별 수집)
    새로운 객체 : 생성 이후 제 역할을 빠르게 수행한 후 금방 쓸모가 없어지는 것
    오랜된 객체 : 일정 시간 이상 동안 살아남은 객체
    -> 이 두가지로 분류해서 관리하는 기법

  • incremental collection(점진적 수집)
    가비지 컬렉션을 여러 부분으로 분리한 후, 각 부분을 별도로 수행합니다. 즉 작업을 분리하여 긴 대기 시간을 여러 개의 짧은 지연으로 분산시킬 수 있게 됩니다.

  • idle-time collection(유휴 시간 수집)
    가비지 컬렉터는 실행에 주는 영향을 최소화하기 위해 cpu가 유휴 상태일 때만 가비지 컬렉션을 실해시킵니다.

profile
초보 개발자의 개발 공간

0개의 댓글