모던 javascript 튜토리얼

가비지 컬렉션

crab. 2022. 6. 24. 08:53
  • 자바스크립트는 눈에 보이지 않는 곳에서 메모리 관리를 수행합니다.
  • 원시값, 객체, 함수 등 우리가 만드는 모든 것은 메모리를 차지합니다.
  • 그렇다면 더는 쓸모 없어지게 된 것들은 어떻게 처리될까요? 지금부턴 자바스크립트 엔진이 어떻게 필요 없는 것을 찾아내 삭제하는지 알아보겠습니다.

가비지 컬렉션 기준

  1. 아래 소개해 드릴 값들은 그 태생부터 도달 가능하기 때문에, 명백한 이유 없이는 삭제되지 않습니다.
  2. 예시:
  • 현재 함수의 지역 변수와 매개변수
  • 중첩 함수의 체인에 있는 함수에서 사용되는 변수와 매개변수
  • 전역 변수
  • 기타 등등

이런 값은 *루트(root)*라고 부릅니다.

  1. 루트가 참조하는 값이나 체이닝으로 루트에서 참조할 수 있는 값은 도달 가능한 값이 됩니다.
  2. 전역 변수에 객체가 저장되어있다고 가정해 봅시다. 이 객체의 프로퍼티가 또 다른 객체를 참조하고 있다면, 프로퍼티가 참조하는 객체는 도달 가능한 값이 됩니다. 이 객체가 참조하는 다른 모든 것들도 도달 가능하다고 여겨집니다. 자세한 예시는 아래에서 살펴보겠습니다.

간단한 예시

// user엔 객체 참조 값이 저장됩니다.
let user = {
  name: "John"
};
  • user의 값을 다른 값으로 덮어쓰면 참조(화살표)가 사라집니다.

user = null;
  • 이제 John은 도달할 수 없는 상태가 되었습니다.
  • John에 접근할 방법도, John을 참조하는 것도 모두 사라졌습니다. 가비지 컬렉터는 이제 John에 저장된 데이터를 삭제하고, John을 메모리에서 삭제합니다.

연결된 객체

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;
  • 삭제한 두 개의 참조 중 하나만 지웠다면, 모든 객체가 여전히 도달 가능한 상태였을 겁니다.
  • 하지만 참조 두 개를 지우면 John으로 들어오는 참조(화살표)는 모두 사라져 John은 도달 가능한 상태에서 벗어납니다.
  • 외부로 나가는 참조는 도달 가능한 상태에 영향을 주지 않습니다.
  • 외부에서 들어오는 참조만이 도달 가능한 상태에 영향을 줍니다. John은 이제 도달 가능한 상태가 아니기 때문에 메모리에서 제거됩니다.
  • John에 저장된 데이터(프로퍼티) 역시 메모리에서 사라집니다.

최적화 기법

  • generational collection(세대별 수집) – 객체를 '새로운 객체’와 '오래된 객체’로 나눕니다. 객체 상당수는 생성 이후 제 역할을 빠르게 수행해 금방 쓸모가 없어지는데, 이런 객체를 '새로운 객체’로 구분합니다. 가비지 컬렉터는 이런 객체를 공격적으로 메모리에서 제거합니다. 일정 시간 이상 동안 살아남은 객체는 '오래된 객체’로 분류하고, 가비지 컬렉터가 덜 감시합니다.
  • incremental collection(점진적 수집) – 방문해야 할 객체가 많다면 모든 객체를 한 번에 방문하고 mark 하는데 상당한 시간이 소모됩니다. 가비지 컬렉션에 많은 리소스가 사용되어 실행 속도도 눈에 띄게 느려지겠죠. 자바스크립트 엔진은 이런 현상을 개선하기 위해 가비지 컬렉션을 여러 부분으로 분리한 다음, 각 부분을 별도로 수행합니다. 작업을 분리하고, 변경 사항을 추적하는 데 추가 작업이 필요하긴 하지만, 긴 지연을 짧은 지연 여러 개로 분산시킬 수 있다는 장점이 있습니다.
  • idle-time collection(유휴 시간 수집) – 가비지 컬렉터는 실행에 주는 영향을 최소화하기 위해 CPU가 유휴 상태일 때에만 가비지 컬렉션을 실행합니다.

요약

지금까지 알아본 내용을 요약해 봅시다.

  • 가비지 컬렉션은 엔진이 자동으로 수행하므로 개발자는 이를 억지로 실행하거나 막을 수 없습니다.
  • 객체는 도달 가능한 상태일 때 메모리에 남습니다.
  • 참조된다고 해서 도달 가능한 것은 아닙니다. 서로 연결된 객체들도 도달 불가능할 수 있습니다.
  • 자바스크립트는 눈에 보이지 않는 곳에서 메모리 관리를 수행합니다.
  • 원시값, 객체, 함수 등 우리가 만드는 모든 것은 메모리를 차지합니다.
  • 그렇다면 더는 쓸모 없어지게 된 것들은 어떻게 처리될까요? 지금부턴 자바스크립트 엔진이 어떻게 필요 없는 것을 찾아내 삭제하는지 알아보겠습니다.

'모던 javascript 튜토리얼' 카테고리의 다른 글

new 연산자와 생성자 함수  (0) 2022.06.26
메서드와 this  (0) 2022.06.25
참조에 의한 객체 복사  (0) 2022.06.23
객체  (0) 2022.06.22
폴리필  (0) 2022.06.21