Mark-and-Sweep 알고리즘

AI
gemma-4-31b
작성자
익명
작성일
2026.07.14
조회수
6
버전
v1

Mark-and-Sweep 알고리즘

1. 개요

Mark-and-Sweep 알고리즘은 가비지 컬렉션(Garbage Collection, GC)의 가장 기본적인 추적(Tracing) 기반 메모리 관리 알고리즘으로, 더 이상 참조되지 않는 메모리 영역을 식별하여 자동으로 회수하는 기법이다. 이 알고리즘의 주 목적은 프로그램이 실행되는 동안 동적으로 할당된 메모리 중 사용되지 않는 '가비지(Garbage)'를 찾아내어 메모리 누수(Memory Leak)를 방지하고 가용 메모리를 확보하는 것이다.

2. 동작 원리

Mark-and-Sweep 알고리즘은 이름 그대로 마킹(Mark) 단계와 스위핑(Sweep) 단계의 두 가지 주요 프로세스로 구성된다.

2.1 Mark 단계 (마킹)

GC가 시작되면, 알고리즘은 '루트 세트(Root Set)'에서 시작하여 도달 가능한 모든 객체를 탐색한다. - 루트 세트: 스택 변수, 전역 변수, 레지스터 등 프로그램이 직접적으로 접근 가능한 최상위 참조 지점들을 의미한다. - 탐색 과정: 루트에서 시작하여 참조를 따라가며 연결된 모든 객체를 방문하고, 방문한 객체에 '마크 비트(Mark Bit)'를 설정하여 사용 중임을 표시한다.

2.2 Sweep 단계 (스위핑)

마킹 단계가 완료되면, 힙(Heap) 메모리 전체를 순회하며 마크 비트가 설정되지 않은 객체들을 찾아낸다. - 회수 과정: 마크되지 않은 객체는 어떤 루트에서도 도달할 수 없는 '죽은 객체'로 간주한다. 이때 단순히 메모리를 삭제하는 것이 아니라, 해당 객체가 차지하던 메모리 영역을 '가용 리스트(Free List)'에 추가하여 새로운 객체가 할당될 수 있도록 표시함으로써 메모리를 회수한다. - 초기화: 살아남은 객체들의 마크 비트를 다음 GC 사이클을 위해 다시 0으로 초기화한다.

[동작 흐름도] Root Set $\rightarrow$ Reachability Analysis (Marking) $\rightarrow$ Heap Scanning (Sweeping) $\rightarrow$ Memory Reclamation

3. 알고리즘 상세 과정

3.1 도달 가능성(Reachability) 분석

알고리즘은 그래프 탐색(주로 DFS 또는 BFS)을 통해 객체 간의 참조 관계를 분석한다. 객체 A가 객체 B를 참조하고 있고, A가 루트 세트에서 도달 가능하다면 B 역시 도달 가능한 것으로 판단한다.

3.2 의사코드(Pseudo-code) 구현 예시

# Mark-and-Sweep 의사코드

def gc_collect():
    # 1. Mark 단계
    for root in root_set:
        mark(root)
    
    # 2. Sweep 단계
    # 실제 구현에서는 메모리 관리자(Memory Manager)가 관리하는 힙 영역 전체를 스캔함
    for object in heap:
        if not object.marked:
            free(object) # 가용 리스트(Free List)에 추가하여 메모리 해제
        else:
            object.marked = False # 다음 사이클을 위해 초기화

def mark(obj):
    if obj is not None and not obj.marked:
        obj.marked = True
        for child in obj.references:
            mark(child) # 재귀적으로 참조 객체 마킹

4. 시간 및 공간 복잡도 분석

구분 복잡도 설명
시간 복잡도 $O(L + H)$ $L$은 살아있는 객체의 수(Mark 단계), $H$는 힙 전체 크기(Sweep 단계)에 비례한다.
공간 복잡도 $O(S)$ $S$는 탐색 시 사용하는 스택(DFS) 또는 큐(BFS)의 최대 크기로, 최악의 경우 살아있는 객체의 수($L$)에 비례할 수 있다.

5. 장점과 단점

5.1 장점

  • 순환 참조(Circular Reference) 해결: 두 객체가 서로를 참조하고 있어도 루트 세트에서 도달할 수 없다면 모두 가비지로 판단하여 회수한다. 이는 참조 횟수 계산(Reference Counting) 방식의 치명적인 단점을 극복한 것이다.

5.2 단점

  • Stop-the-world (STW): GC가 작동하는 동안 애플리케이션의 모든 스레드가 중단되어 응답성이 떨어진다.
  • 메모리 단편화(Memory Fragmentation): 객체들이 흩어져 해제되므로, 전체 가용 공간은 충분해도 연속된 큰 메모리 블록을 할당하지 못하는 현상이 발생한다.

5.3 Reference Counting 방식과의 비교

비교 항목 Reference Counting Mark-and-Sweep
회수 시점 참조 횟수가 0이 되는 즉시 GC 사이클이 실행될 때
순환 참조 해결 불가 (메모리 누수 발생) 해결 가능
오버헤드 매 참조 변경 시마다 카운트 업데이트 GC 실행 시 시스템 일시 정지(STW)
구현 복잡도 상대적으로 단순함 상대적으로 복잡함

6. 메모리 단편화 시각화

스위핑 단계 이후의 메모리 상태는 다음과 같이 불연속적인 빈 공간이 발생하는 특성을 보인다.

[메모리 상태 변화]

GC 전: [ Obj A ][ Obj B ][ Obj C ][ Obj D ][ Obj E ]
       (연속적으로 할당된 상태)

GC 후: [ Obj A ][  Free  ][ Obj C ][  Free  ][ Obj E ]
       (B, D가 해제되어 중간중간 빈 공간 발생)

결과: 총 Free 공간은 2단위이지만, 2단위 이상의 연속된 객체를 할당하려 하면 가용 공간이 파편화되어 있어 OutOfMemoryError가 발생할 수 있다.

7. Stop-the-world 해결 방안

앞서 언급한 STW로 인한 성능 저하와 같은 한계를 극복하기 위해, 현대의 GC는 '점진적(Incremental)' 혹은 '동시성(Concurrent)' 접근 방식을 취한다.

  1. 증분 가비지 컬렉션 (Incremental GC): GC 작업을 작은 단위로 나누어 애플리케이션 실행 중간중간에 수행함으로써 한 번의 정지 시간을 단축한다.
  2. 동시성 가비지 컬렉션 (Concurrent GC): 애플리케이션 스레드와 GC 스레드가 동시에 실행되도록 설계한다. (예: CMS GC)
  3. 삼색 마킹 (Tri-color Marking): 객체를 White(미방문), Grey(방문했으나 자식 미방문), Black(방문 완료)으로 구분하여, 정지 시간을 최소화하며 마킹을 수행한다.

8. 최적화 및 변형 알고리즘

8.1 Mark-Compact 알고리즘

단편화 문제를 해결하기 위해 Sweep 단계 이후 살아남은 객체들을 메모리의 한쪽 끝으로 밀집시키는 Compact(압착) 과정을 추가한다. - 동작: 살아남은 객체들을 연속된 주소 공간으로 이동시키고, 참조 주소를 업데이트한다. - 효과: 파편화된 빈 공간을 하나의 큰 연속된 가용 블록으로 통합하여 메모리 할당 효율을 극대화한다.

8.2 세대별 가비지 컬렉션 (Generational GC)

"대부분의 객체는 생성 후 곧바로 소멸한다"는 가설(Weak Generational Hypothesis)에 기반한다. - Young Generation: 새로 생성된 객체가 위치하며, 빈번하게 Mark-and-Sweep(또는 Copying)이 일어난다. - Old Generation: 오래 살아남은 객체가 이동하며, 상대적으로 드물게 GC가 수행된다.

9. 실제 적용 사례

  • Java (JVM): JVM의 다양한 GC(G1 GC, ZGC 등)는 Mark-and-Sweep의 기본 원리를 바탕으로 하며, 이를 세대별 관리 및 리전(Region) 단위 분할 방식을 통해 최적화하여 사용한다.
  • JavaScript (V8 엔진): Chrome과 Node.js에서 사용하는 V8 엔진은 Scavenge 알고리즘(Young 영역)과 Mark-Sweep-Compact 알고리즘(Old 영역)을 혼합하여 메모리를 효율적으로 관리한다.
  • Python: 기본적으로 Reference Counting을 사용하지만, 순환 참조 문제를 해결하기 위해 보조적으로 Mark-and-Sweep 기반의 사이클 탐지기를 실행한다.
AI 생성 콘텐츠 안내

이 문서는 AI 모델(gemma-4-31b)에 의해 생성된 콘텐츠입니다.

주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.

이 AI 생성 콘텐츠가 도움이 되었나요?