"매 도달 불가능 (unreachable) 한 객체를 자동으로 회수하는 runtime memory manager". 1959 LISP의 mark-and-sweep 부터 현대의 ZGC/Shenandoah/G1 까지 — 매 generational + concurrent + region-based 방향으로 진화. 매 sub-millisecond pause 의 실용화 (2024+).
매 핵심
매 GC 의 근본 작업
Mark: GC root (stack, globals, registers) 부터 reachable graph traversal.
Sweep / Compact / Copy: unreachable 객체의 회수 + 매 fragmentation 의 처리.
매 주요 알고리즘
Mark-and-Sweep: 매 simple, 매 fragmentation 발생.
Mark-Compact: 매 sweep 후 live object 의 compact — fragmentation X.
Copying (Cheney): 매 from-space → to-space 의 live copy. 매 generational young gen 에 사용.
Generational: 매 weak generational hypothesis — 매 young die young. 매 young gen frequent + old gen rare.
Concurrent / Incremental: 매 mutator thread 와 동시 실행 — pause 의 최소화.
Region-based (G1, ZGC, Shenandoah): 매 heap 의 region 분할 — 매 partial collection.
매 응용
JVM (G1 default since Java 9, ZGC production since Java 17, Shenandoah).
Go (concurrent tri-color mark-sweep, sub-ms pause).
.NET CLR (generational + LOH).
CPython (reference counting + cycle detector).
💻 패턴
Tri-color Marking (concurrent GC 의 기반)
# Tri-color invariant: White (unmarked), Gray (marked, children pending), Black (done)WHITE,GRAY,BLACK=0,1,2deftri_color_mark(roots,heap):forobjinheap:obj.color=WHITEgray_set=set()forrinroots:r.color=GRAYgray_set.add(r)whilegray_set:obj=gray_set.pop()forchildinobj.refs:ifchild.color==WHITE:child.color=GRAYgray_set.add(child)obj.color=BLACK# White = unreachable -> sweepreturn[oforoinheapifo.color==WHITE]
Write Barrier (concurrent GC 의 invariant 유지)
// Dijkstra-style: black -> white write 발생 시 child를 gray로 승격
voidwrite_barrier(Object*parent,Object**field,Object*new_val){if(parent->color==BLACK&&new_val&&new_val->color==WHITE){new_val->color=GRAY;gray_queue_push(new_val);}*field=new_val;}
Generational Allocation (bump allocator)
structYoungGen{start: *mutu8,top: *mutu8,end: *mutu8}implYoungGen{fnalloc(&mutself,size: usize)-> Option<*mutu8>{unsafe{letnew_top=self.top.add(size);ifnew_top>self.end{returnNone;}// trigger minor GC
letp=self.top;self.top=new_top;Some(p)}}}
Reference Counting + Cycle Detection (CPython)
classObj:def__init__(self):self.refcount=1defincref(self):self.refcount+=1defdecref(self):self.refcount-=1ifself.refcount==0:forchildinself.refs:child.decref()free(self)# Cycle: a.refs=[b], b.refs=[a] -> refcount 영원히 >0 -> cycle collector 필요
Finalizer (resource cleanup, careful)
// Java AutoCloseable + try-with-resources >>> finalize() (deprecated in Java 9+)try(varconn=DriverManager.getConnection(url)){// use conn}// auto-close, deterministic
Soft / Weak / Phantom Reference
WeakReference<Cache>ref=newWeakReference<>(cache);// GC가 free하면 ref.get() == null. Cache 구현에 자주 사용