--- id: wiki-2026-0508-마크-스윕-mark-sweep title: 마크 스윕(Mark Sweep) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Mark-Sweep, Mark and Sweep, Tracing GC] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [gc, memory, runtime, algorithm, jvm, v8] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: C/C++/Java framework: JVM/V8/Go runtime --- # 마크 스윕(Mark Sweep) ## 매 한 줄 > **"매 root 에서 reachable 한 것만 매 mark, 매 unmarked 는 매 sweep"**. 매 1960 McCarthy 의 LISP 가 매 origin, 매 60+ 년 동안 매 tracing GC 의 backbone. 매 modern 변형 (G1, ZGC, Shenandoah, V8 Orinoco) 매 모두 매 mark-sweep 의 evolution. ## 매 핵심 ### 매 두 phase 1. **매 Mark**: 매 root (stack, register, global) 에서 매 reachable graph 매 traverse, 매 mark bit 설정. 2. **매 Sweep**: 매 heap 전체를 매 scan, 매 unmarked block 을 매 free list 로. ### 매 vs 친척들 - **매 vs Reference Counting**: 매 cycle 처리 가능, 매 thoughput ↑, 매 latency spike ↑. - **매 vs Copying (Cheney)**: 매 fragmentation 발생, 매 메모리 효율 ↑ (매 copy 가 1/2 reserve X). - **매 vs Mark-Compact**: 매 sweep 후 compact 추가 — 매 fragmentation 해결. ### 매 Tri-color abstraction - **매 White**: 매 unvisited (sweep 대상). - **매 Grey**: 매 reachable, 매 children 미 traverse. - **매 Black**: 매 reachable + 매 children traversed. - 매 invariant: 매 black → white edge 의 X (매 보장 시 concurrent OK). ### 매 Modern 변형 - 매 Generational: 매 young/old, 매 minor/major GC. - 매 Concurrent: 매 mark 를 매 mutator 와 병행. - 매 Incremental: 매 small chunk 씩 매 stop. - 매 Region-based (G1): 매 heap 을 region 으로 split. ## 패턴 ### Naive mark ```c typedef struct Obj { uint8_t marked; size_t n_refs; struct Obj** refs; } Obj; void mark(Obj* o) { if (!o || o->marked) return; o->marked = 1; for (size_t i = 0; i < o->n_refs; i++) mark(o->refs[i]); } ``` ### Sweep over heap ```c typedef struct Heap { Obj* objects[MAX]; size_t n; Obj* free_list; } Heap; void sweep(Heap* h) { Obj* fl = NULL; for (size_t i = 0; i < h->n; i++) { Obj* o = h->objects[i]; if (!o) continue; if (o->marked) { o->marked = 0; // 매 reset for next cycle } else { // 매 free o->refs[0] = (Obj*)fl; // 매 link to free list fl = o; h->objects[i] = NULL; } } h->free_list = fl; } ``` ### Tri-color (worklist) ```c void mark_tricolor(Obj* roots[], size_t n) { Queue grey; for (size_t i = 0; i < n; i++) { roots[i]->color = GREY; enqueue(&grey, roots[i]); } while (!empty(&grey)) { Obj* o = dequeue(&grey); for (size_t i = 0; i < o->n_refs; i++) { Obj* c = o->refs[i]; if (c && c->color == WHITE) { c->color = GREY; enqueue(&grey, c); } } o->color = BLACK; } } ``` ### Write barrier (concurrent invariant) ```c // 매 Dijkstra-style: 매 black 이 white 를 가리키지 않도록 void write_barrier(Obj* parent, size_t i, Obj* child) { if (parent->color == BLACK && child && child->color == WHITE) { child->color = GREY; enqueue(&grey, child); } parent->refs[i] = child; } ``` ### Generational hook (write barrier on old → young) ```c // 매 remembered set 에 매 old object 추가 void gen_write_barrier(Obj* parent, size_t i, Obj* child) { parent->refs[i] = child; if (parent->gen == OLD && child && child->gen == YOUNG) remembered_set_add(parent); } ``` ### JVM tuning (G1) ```bash java -XX:+UseG1GC \ -XX:MaxGCPauseMillis=100 \ -XX:G1HeapRegionSize=16m \ -Xms4g -Xmx4g \ -Xlog:gc*:file=gc.log \ -jar app.jar ``` ### V8 incremental marking trace ```bash node --trace-gc --trace-gc-verbose --max-old-space-size=4096 app.js ``` ## 매 결정 기준 | 상황 | GC | |---|---| | 매 simple, 매 single-thread | Mark-Sweep | | 매 fragmentation 의 우려 | Mark-Compact | | 매 short-lived dominant | Generational + copying young | | 매 latency-critical (<10ms) | ZGC / Shenandoah | | 매 throughput-critical | Parallel/Throughput GC | | 매 ref-cycle 매 잦음 | Tracing GC (RC X) | **기본값**: 매 JVM 8GB 초과 = 매 G1 (default), 매 latency 절실 = 매 ZGC. ## Graph - 부모: [[Garbage Collection]] · [[Memory Management]] - 변형: [[Mark-Compact]] · [[Generational GC]] · [[Concurrent GC]] · [[ZGC]] · [[Shenandoah]] - 응용: [[JVM]] · [[V8]] · [[Go runtime]] · [[CRuby]] - Adjacent: [[Tri-color Marking]] · [[Write Barrier]] · [[Reference Counting]] ## LLM 활용 **언제**: 매 GC 알고리즘 설명, 매 JVM/V8 tuning, 매 GC log 분석, 매 toy GC 작성. **언제 X**: 매 production 의 직접 GC patch (매 risk ↑) — 매 review 만. ## 안티패턴 - **매 Frequent full GC trigger**: 매 -Xmx 부족 / 매 leak. - **매 No write barrier in concurrent**: 매 missed object 의 free. - **매 Recursive mark on deep graph**: 매 stack overflow — 매 worklist 사용. - **매 Tuning without log**: 매 -Xlog:gc* / -verbose:gc 매 필수. - **매 Force System.gc()**: 매 hint, 매 흔히 매 worse latency. ## 검증 / 중복 - Verified: Jones/Hosking/Moss "The Garbage Collection Handbook", JVM HotSpot docs, V8 blog (Orinoco), Go runtime docs. - 신뢰도 A. ## Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — mark-sweep tri-color/write barrier/tuning 작성 |