logo

DowanKim

20. 가비지 컬렉션

2026년 4월 11일

자바스크립트

1. 도달 가능성 (Reachability)

자바스크립트 메모리 관리의 핵심은 **"지금 이 값을 사용할 수 있는가?"**입니다. 이 기준을 **'도달 가능성'**이라고 부릅니다.

  • 루트(Roots): 태생부터 도달 가능한 값들입니다. (삭제 불가)
    • 현재 함수의 지역 변수, 매개변수
    • 중첩 함수 체인의 변수들
    • 전역 변수 등
  • 도달 가능한 값: 루트에서 시작해 참조(화살표)를 따라가서 어떻게든 닿을 수 있는 값은 메모리에서 유지됩니다.
  • 가비지 컬렉터: 모든 객체를 감시하며, 루트에서 도달할 수 없게 된 객체는 메모리에서 삭제합니다.

2. 도달할 수 없는 섬 (Unreachable Islands)

참조가 서로 얽혀 있어도 루트(Root)와의 연결이 끊어지면 메모리에서 통째로 사라집니다.

  • 특징: 객체 A와 B가 서로를 참조하고 있더라도(순환 참조), 외부에서 이들을 참조하는 루트가 사라지면 가비지 컬렉션의 대상이 됩니다.
  • 교훈: 객체 내부에서 서로를 참조하는 것보다, **"외부(루트)에서 들어오는 참조가 있는가"**가 훨씬 중요합니다.

3. 내부 알고리즘: Mark-and-Sweep

가비지 컬렉션이 실제로 동작하는 기본 알고리즘입니다. 엔진은 주기적으로 다음 단계를 거칩니다.

  1. Mark (마킹): 루트(Root) 정보를 수집하고 기억합니다.
  2. Visit (방문): 루트가 참조하는 객체들을 방문하여 마크합니다. 마크된 객체가 참조하는 다른 객체들도 계속 따라가며 마크합니다.
  3. Sweep (삭제): 마크되지 않은(페인트가 칠해지지 않은) 모든 객체를 메모리에서 삭제합니다.

🚀 4. 엔진의 최적화 기법

가비지 컬렉션은 CPU 리소스를 소모하므로, 모던 엔진(V8 등)은 성능 저하를 막기 위해 여러 기법을 씁니다.

기법설명
세대별 수집 (Generational)신규 객체는 공격적으로 제거하고, 오래 살아남은 객체는 덜 감시합니다.
점진적 수집 (Incremental)한 번에 다 하지 않고 작업을 쪼개서 수행해 실행 지연을 분산시킵니다.
유휴 시간 수집 (Idle-time)CPU가 한가할 때만 청소부(GC)를 돌립니다.

🎙️ 기술 면접 대비 (Interview Questions)

Q1. 자바스크립트의 가비지 컬렉션 기준은 무엇인가요? (기초)

답변: **'도달 가능성(Reachability)'**을 기준으로 합니다. 루트(전역 변수, 지역 변수 등)에서 시작해 참조 체인을 통해 접근할 수 있는 객체는 유지하고, 어떤 경로로도 도달할 수 없게 된 객체는 메모리에서 자동으로 제거합니다.

Q2. '순환 참조'가 발생해도 가비지 컬렉션이 이루어질 수 있나요? (중급)

답변: 네, 가능합니다. 객체들이 서로를 참조하고 있더라도(도달할 수 없는 섬), 그 집합 자체가 전역 루트와 연결되어 있지 않다면 마크-앤-스윕 알고리즘에 의해 통째로 메모리에서 삭제됩니다.

Q3. 가비지 컬렉션으로 인한 성능 저하를 엔진은 어떻게 해결하나요? (심화)

답변: 모든 객체를 한 번에 검사하면 'Stop-the-world' 현상(실행 멈춤)이 발생하므로, 작업을 쪼개서 하는 점진적 수집, 객체의 수명에 따라 빈도를 조절하는 세대별 수집, CPU가 쉴 때만 동작하는 유휴 시간 수집 등의 최적화 기법을 사용합니다.


💡 기억해야 할 중요한 내용

  • 수동 삭제는 불가능합니다. user = null 처럼 참조를 끊어 도달 불가능하게 만들 수는 있지만, delete user 같은 명령어로 메모리를 즉시 직접 비울 수는 없습니다. 그건 전적으로 엔진의 몫입니다.
  • 루트를 조심하세요. 전역 변수는 프로그램 종료 시까지 메모리에 남으므로, 불필요한 전역 변수 남발은 메모리 누수의 주범이 됩니다.