[JS] 가비지 컬렉션이 뭐에요?

kimminjunnn·2025년 5월 25일

CS

목록 보기
26/34

가비지 컬렉션 (Garbage Collection, GC)

가비지 컬렉션에 대해 검색하면 자바스크립트가 아닌 자바(Java)의 가비지 컬렉션에 대한 정보가 많이 보인다.

왜 검색하면 전부 자바(Garbage Collection in Java) 이야기일까?

가비지 컬렉션(GC)은 언어 자체의 기능이라기보다는, 런타임 환경에서 작동하는 기능이다.

그래서 "어떤 언어가 GC를 어떻게 구현했는가"가 더 중요하게 여겨진다.

그 중에서도 자바(Java)는 GC를 가장 적극적이고 체계적으로 적용한 대표적인 언어이기 때문에, 관련 설명 자료가 많고 잘 정리되어 있다.

특히 자바에서는 GC의 내부 동작 원리, 메모리 구조(Heap, Stack), 알고리즘(Mark & Sweep, Generational GC 등) 등이 구체적으로 문서화되어 있어,
컴퓨터공학에서 GC 개념을 공부할 때 자주 인용되는 대표 사례가 된다.

그렇다면 자바스크립트의 가비지 컬렉션은 어떻게 작동할까?

자바스크립트도 가비지 컬렉션 기능을 내장하고 있다.
우리가 사용하는 JS 코드가 브라우저나 Node.js 환경에서 실행될 때,
해당 환경의 자바스크립트 엔진(V8, SpiderMonkey 등)이 메모리를 자동으로 관리해준다.
자바처럼 우리가 직접 조작할 일은 거의 없고, 자바스크립트 엔진이 알아서 해주는 쪽에 가깝다.


자바스크립트는 "도달 가능성(reachability)"이라는 개념을 기준으로
필요한 값은 남겨두고, 더 이상 접근할 수 없는 값은 메모리에서 제거한다.

도달 가능한 값이란?

‘도달 가능한(reachable)’ 값은 쉽게 말해 어떻게든 접근하거나 사용할 수 있는 값을 의미한다.
도달 가능한 값은 메모리에서 삭제되지 않는다.

아래에 있는 값들은 그 태생부터 도달 가능하기 때문에, 명백한 이유 없이는 삭제되지 않는다.

  • 지금 실행 중인 함수의 지역 변수 or 매개변수
  • 중첩 함수의 체인에 있는 함수에서 사용되는 변수 or 매개변수
  • 전역 변수

이런 값들은 루트(Root)라고 부른다.
루트에서 참조되는 값들은 도달 가능하다고 간주되고,
그 값이 또 다른 객체를 참조하면 그것도 도달 가능한 값이 된다.

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


예시 1: 단순 참조 제거

let user = { name: "John" };
user = null;

→ 더 이상 John이라는 객체를 참조하는 변수가 없기 때문에
GC는 이 객체를 메모리에서 제거할 수 있다.


예시 2: 참조가 남아 있는 경우

let user = { name: "John" };
let admin = user;

user = null;

user는 비워졌지만 admin이 여전히 John을 참조하고 있으므로,
메모리에서 제거되지 않는다.
admin = null까지 해야 GC 대상이 된다.


예시 3: 연결된 객체 간의 참조

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;
  • 이 경우 두 객체는 서로를 참조하고 있지만,
  • 루트에서 더 이상 참조되지 않으면 GC 대상이 된다.
  • 외부에서 들어오는 참조만이 중요하다.

예시 4: 도달할 수 없는 섬

family = null;

  • 이제 John, Ann은 여전히 서로를 참조하고 있지만
  • 루트에서 시작해 도달할 수 없으므로 섬처럼 고립되어 GC 대상이 된다

내부 알고리즘: mark-and-sweep

자바스크립트 엔진은 mark-and-sweep이라는 알고리즘으로 GC를 수행한다.

  1. 루트에서 시작해서 도달 가능한 객체들을 모두 mark 한다
  2. 한 번 방문한 객체는 다시 방문하지 않는다
  3. 마지막까지 도달 가능한 객체만 남기고, 나머지는 메모리에서 제거

이 과정을 페인트로 칠한다고 상상하면 쉽다.
루트에서 출발해서 참조를 따라가며 객체에 색을 칠하고,
색칠이 안 된 객체는 쓸모 없다고 판단해 버린다.


모던 엔진의 최적화 방식

자바스크립트 엔진은 GC를 더 효율적으로 하기 위해 다양한 전략을 쓴다:

  • Generational Collection: 세대별 수집 - 새로 생긴 객체는 빨리 버리고, 오래된 객체는 덜 감시
  • Incremental Collection: 점진적 수집 - 한번에 다 지우지 않고 조금씩 나눠서 처리, 가비지 컬렉션에 한꺼번에 많은양에 리소스가 사용되는 것을 방지
  • Idle-Time Collection: 유휴 시간 수집 - 브라우저가 한가할 때 처리해서 성능 저하를 막음

정리

  • 가비지 컬렉션은 자바스크립트 엔진이 자동으로 처리한다
  • 객체는 도달 가능할 때만 메모리에 남는다
  • 서로 참조하고 있다고 해서 메모리에 남는 건 아니다
  • 외부에서 참조할 수 없는 객체는 섬처럼 고립되어 GC 대상이 된다
  • 개발자는 GC를 직접 제어하지 않지만, 불필요한 참조를 남기지 않도록 코드를 잘 짜는 게 중요하다
profile
Frontend Engineers

0개의 댓글