Article background image
가비지 컬렉션(Garbage Collection)
JavaScript
2021.09.01

가비지 컬렉션(Garbage Collection)

정의

할당된 메모리가 쓸모없어졌을 때 자동으로 해제시켜주는 방법

메모리 라이프 사이클

  1. 필요할 때 메모리 할당
  2. 읽기/쓰기로 값 사용
  3. 필요 없으면 해제

메모리 할당

// 기본형 값 할당
var a = 123;
var b = '123';

// 객체 할당
var obj = {
  abc: 1,
  func: function() {}
};

// 함수 선언 할당(함수 객체)
function func(a) {
  return console.log(a);
}

// 함수 호출하여 할당
var date = new Date();

값 사용

// ex 1)
var num1 = 5;
var num2 = 5;
var num3 = num1 + num2;

// ex 2)
function sum(a, b) {
  return a + b;
}
var total = sum(5, 5);

메모리 해제

가비지 컬렉터(Garbage Collector)가 할당된 메모리를 계속 추적하고 사용하지 않는 메모리를 발견하면 회수한다. 사용하지 않는 메모리를 판단하는 방법이 가비지 컬렉션의 핵심이다.

사용하지 않는 메모리 판별

가비지 컬렉션은 참조(Reference) 상태를 기준으로 메모리 해제 대상으로 지정(수집)하고 해제한다.

방식 1) Referennce-counting

샘플 코드(MDN)

// x = { a: { b: 2 } }
var x = {
  a: {
    b: 2
  }
};

// 'x'와 'y' 둘 다 '{ a: { b: 2 } }' 객체를 참조함
var y = x;

// '{ a: { b: 2 } }' 객체는 y만 참조함
// x는 가비지 컬렉션 대상 후보가 될 수 있음
x = 1;

// z가 '{ a: { b: 2 } }'의 일부인 a 속성의 '{ b: 2 }' 객체를 참조함
var z = y.a;

// y는 가비지 컬렉션 대상 후보가 될 수 있음
y = "mozilla";

// '{ a: { b: 2 } }'를 참조하는 대상은 없어졌지만, z가 아직 '{ a: { b: 2 } }'의 일부인 a를 참조하고 있음

// z는 가비지 컬렉션 대상 후보가 될 수 있음
z = null;

// 그 어느 것도 '{ a: { b: 2 } }' 객체를 참조하지 않게 됨
// x, y, z는 참고하고 있는 객체가 없으므로 현재 scope의 처리가 끝나면 가비지 컬렉터에 의해 메모리 해제 됨

문제점

아래와 같이 순환 참조가 된 상태의 경우, 수집 대상에 포함되지 않아 메모리 누수 발생

function memoryLeak() {
  var ref1 = {};
  var ref2 = {};
  ref1.a = ref2;
  ref2.a = ref1;
}

memoryLeak();

Internet Explorer 6, 7은 이 문제를 갖고 있음

방식 2) Mark-and-sweep

참조 연결이 닿을 수 있는 객체들(Reachable Objects)을 체크하고 체크되지 않은 대상은 가비지 컬렉션 대상으로 지정하여 해제한다.

Java-GC-mark-and-sweep

위 그림과 같이 최상위(전역) scrope에 있는 roots 라고 불리는 오브젝트 집합부터 시작해서 자식 오브젝트의 참조 끝까지 순회한다. 순회가 끝나면 닿지 않는 객체들(Non-Reachable Objects)에 대해 메모리를 해제한다. 가비지 컬렉션은 런타임 환경에서 실행되므로 웹 사이트의 성능에 영향을 덜 미치기 위하여 최적화가 적용되어 있다.

대표 최적화 기법 3가지

Generational collection

새로운 객체, 오래된 객체로 분류한다. 즉시 사용되고 사라질 가능성이 있는 최근에 생성된 새로운 객체 위주로 우선 감시하고, 계속 사용되고 있는 오래된 객체는 상대적으로 덜 감시한다.

incremental collection

참조 관계의 개수가 많아지면 체크(Mark)하는 데에 시간이 오래 걸리므로 가비지 컬렉션을 여러 개로 분리하여 각자 별도로 수행한다. 분리, 변경사항 추적에 추가 작업이 필요하지만, 짧은 간격으로 실행할 수 있는 장점이 있다.

idle-time collection

가비지 컬렉터는 CPU가 유휴 상태일 때에만 가비지 컬렉션을 실행한다.

메모리 누수

잘 정리된 글이 있어서 대체

Reference

블로그에 방문해주셔서 감사합니다 🥳
© 2021 Developer Myoung Ho Kim, Powered By Gatsby.