--- id: wiki-2026-0508-cheneys-algorithm title: Cheney's Algorithm category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Cheney GC, Semi-space Collector, Copying GC] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [gc, memory, algorithm, runtime] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: C/Rust framework: runtime/GC --- # Cheney's Algorithm ## 매 한 줄 > **"매 stop-and-copy GC 의 BFS-style two-finger traversal"**. 1970년 C.J. Cheney 가 제시한 copying garbage collector 의 표준 algorithm — recursion 없이 queue-style 로 live object 를 from-space 에서 to-space 로 evacuate. 매 modern V8/SpiderMonkey young generation, OCaml minor heap, MLton 의 baseline. ## 매 핵심 ### 매 semi-space 구조 - Heap 을 두 개의 equal-sized region 으로 split: from-space, to-space. - Allocation 은 from-space 의 bump pointer 만 증가. - GC 시 live object 를 to-space 로 copy 후 role swap. ### 매 two pointers - `scan`: to-space 에서 아직 children 추적 안 한 boundary. - `free`: to-space 의 next allocation slot. - `scan == free` 이면 traversal 종료. ### 매 응용 1. V8 young-gen scavenger (Node.js, Chrome). 2. OCaml minor heap collection. 3. SBCL, MLton 의 default GC. ## 💻 패턴 ### Core Cheney loop (C) ```c void* to_space; size_t scan, free_; void* copy(void* obj) { if (is_forwarded(obj)) return forward_addr(obj); size_t sz = size_of(obj); void* dst = (char*)to_space + free_; memcpy(dst, obj, sz); set_forward(obj, dst); free_ += sz; return dst; } void cheney_gc(void** roots, size_t n) { free_ = scan = 0; for (size_t i = 0; i < n; i++) roots[i] = copy(roots[i]); while (scan < free_) { void* obj = (char*)to_space + scan; for_each_pointer_field(obj, p) { *p = copy(*p); } scan += size_of(obj); } swap(from_space, to_space); } ``` ### Forwarding pointer trick ```c // Object header overlap: live header OR forwarding pointer. struct header { uintptr_t tag_or_fwd; }; #define IS_FWD(h) ((h)->tag_or_fwd & 1) #define FWD_PTR(h) ((void*)((h)->tag_or_fwd & ~1)) #define SET_FWD(h, dst) ((h)->tag_or_fwd = (uintptr_t)(dst) | 1) ``` ### Allocation (post-GC) ```c void* alloc(size_t sz) { if (free_ + sz > SEMI_SIZE) cheney_gc(roots, n_roots); if (free_ + sz > SEMI_SIZE) abort(); // OOM void* p = (char*)to_space + free_; free_ += sz; return p; } ``` ### V8-style scavenger (simplified) ```cpp void Scavenger::Process() { while (!worklist_.empty()) { HeapObject obj = worklist_.Pop(); obj->IterateBody(this); // visits each pointer field } } void Scavenger::VisitPointer(Object** slot) { HeapObject obj = HeapObject::cast(*slot); if (Heap::InFromSpace(obj)) { HeapObject target = EvacuateObject(obj); *slot = target; } } ``` ### Generational tweak ```c // Young gen uses Cheney; old gen uses mark-sweep. // Promotion: if object survives N scavenges, copy to old-gen instead of to-space. if (age(obj) >= PROMOTION_THRESHOLD) dst = old_gen_alloc(sz); else dst = (char*)to_space + free_; ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Short-lived allocation 多 | Cheney (semi-space) — fast bump alloc | | Large heap, low live ratio | Cheney 우수 (cost ∝ live, not heap) | | Mostly-live mature data | Mark-sweep / mark-compact | | Real-time constraints | Incremental / concurrent GC (Shenandoah, ZGC) | | Memory tight (mobile) | Mark-sweep (no 2× overhead) | **기본값**: Young generation 에 Cheney, old generation 에 mark-compact (generational hypothesis). ## 🔗 Graph - 부모: [[Garbage Collection]] · [[Memory Management]] - 변형: [[Mark-Sweep]] - 응용: [[V8 Engine]] · [[Nodejs]] - Adjacent: [[Write Barrier]] ## 🤖 LLM 활용 **언제**: GC 설명, runtime internals 분석, language implementation 설계 시. **언제 X**: Application-level memory tuning (use language-specific profiler 대신). ## ❌ 안티패턴 - **Naive recursive copy**: stack overflow 가능 — Cheney 의 queue 방식 사용. - **Forgetting forward check**: 동일 object 두 번 copy → 데이터 corrupt. - **Pointer 누락**: stack/register/global root scan 빠짐 → dangling pointer. - **Pinning ignored**: native pointer 가 from-space object 가리키는 동안 GC → crash. ## 🧪 검증 / 중복 - Verified (Cheney 1970 CACM paper, V8/SpiderMonkey source). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — Cheney GC algorithm 의 BFS copy + V8 scavenger 패턴 |