--- id: cs-memory-management-patterns title: Memory Management — GC / arena / RC / ownership category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [cs, memory, vibe-coding] tech_stack: { language: "C++ / Rust", applicable_to: ["CS"] } applied_in: [] aliases: [memory management, garbage collection, RC, reference counting, arena, ownership, RAII] --- # Memory Management Patterns > Memory 의 알고리즘. **GC, arena, ref count, ownership (Rust)**. ## 📖 핵심 개념 - Stack vs heap. - Manual free vs auto. - GC (mark-sweep, generational). - RC (auto, cycle). - Ownership (Rust). ## 💻 코드 패턴 ### Stack vs heap ``` Stack: - Function call frame. - LIFO. - 빠름. - 작은 (1-8 MB). Heap: - 동적 alloc. - 큰. - Free 필요 (manual or GC). ``` ### C / C++ manual ```c int* arr = malloc(100 * sizeof(int)); // 사용. free(arr); ``` → Forget = leak. Double-free = crash. ### C++ RAII ```cpp { std::vector v(100); // 사용. } // 자동 destroy (RAII). ``` → Scope 끝 = destructor. ### Smart pointer (C++) ```cpp auto p = std::make_unique(); // exclusive. auto s = std::make_shared(); // shared (RC). auto w = std::weak_ptr(s); // non-owning. ``` → unique = single owner. shared = ref count. weak = no own (cycle 방지). ### Rust ownership ```rust let s = String::from('hello'); let s2 = s; // moved. // println!('{}', s); // ❌ s 가 moved. fn take(s: String) {} take(s2); // moved. // println!('{}', s2); // ❌ ``` → Compile-time. No GC. ### Rust borrow ```rust fn borrow(s: &String) { println!('{}', s); } let s = String::from('hello'); borrow(&s); println!('{}', s); // OK — borrow 끝. ``` → Read borrow (multiple). Write borrow (exclusive). ### Rust Arc / Rc ```rust use std::rc::Rc; let a = Rc::new(MyData); let b = a.clone(); // count = 2. // Drop = count--. ``` → Single-threaded. ```rust use std::sync::Arc; let a = Arc::new(MyData); let b = a.clone(); // atomic count. ``` → Multi-thread. ### Garbage Collection (GC) ``` Mark-Sweep: - Reachable 인 root → mark. - Unmarked = free. - Stop-the-world. Generational: - Young / old generation. - Young 가 자주 GC (대부분 die). - Old 가 가끔. Concurrent (Java G1, ZGC): - Application + 동시. - Pause time ↓. ``` ### Java GC tuning ```bash java -XX:+UseG1GC -Xmx4g -Xms4g app.jar java -XX:+UseZGC -Xmx16g app.jar # large heap, low pause. ``` ### Go GC ``` Concurrent + tri-color mark. - 1 ms pause typical. - 자체 tune 안 됨. - GOGC env var. ``` ```bash GOGC=200 # GC 가 less frequent (memory ↑). ``` ### Python ref count + GC ``` Ref count + cycle detector. - 매 object 가 count. - Count 0 = free. - Cycle = generational GC. ``` ```python import sys sys.getrefcount(obj) ``` ### JS GC (V8) ``` Generational + concurrent mark-sweep. - 매 minor GC = young (frequent). - Major GC = old (rare). - Tuning = generally 안 함. ``` → Memory leak 가 흔함 (closure, listener). ### Memory leak in JS ```ts // ❌ Closure 가 외부 변수 retain function setup() { const big = new Array(1000000); return () => console.log('hi'); // big 도 retain. } const fn = setup(); // big 가 GC 안. ``` ```ts // ❌ Event listener window.addEventListener('resize', handler); // handler 가 ref. Forever. // ✅ window.addEventListener('resize', handler, { signal: ac.signal }); ac.abort(); ``` ### Arena allocation ``` 모든 alloc 가 1 arena. Arena reset 시 모든 free. → Game / web request frame. - 매 frame / request 의 arena. - Reset = O(1). ``` ```rust use bumpalo::Bump; let arena = Bump::new(); let v = arena.alloc(MyData { ... }); // ... 매 frame 의 alloc. // 매 frame 끝: drop(arena); // 모든 free. ``` → Game engine 친화. ### Pool allocation ```rust struct Pool { items: Vec, free: Vec, } impl Pool { fn alloc(&mut self, item: T) -> usize { if let Some(idx) = self.free.pop() { self.items[idx] = item; idx } else { self.items.push(item); self.items.len() - 1 } } fn free(&mut self, idx: usize) { self.free.push(idx); } } ``` → 같은 size object 의 fast alloc / free. ### Reference cycle ```ts class Node { constructor(public next?: Node) {} } const a = new Node(); const b = new Node(); a.next = b; b.next = a; // cycle. // JS GC 가 detect (mark-sweep). // 옛 ref count 만 = leak. ``` → Modern GC 가 cycle 처리. ### WeakRef / WeakMap (JS) ```ts const cache = new WeakMap(); cache.set(user, 'cached value'); // User 가 GC 됨 = cache entry 도. ``` → Memory leak 방지. ### iOS / macOS ARC ```swift class Person { var partner: Person? } let alice = Person() let bob = Person() alice.partner = bob // strong. bob.partner = alice // strong → cycle. // → Memory leak. ``` ```swift class Person { weak var partner: Person? // weak — no retain. } ``` ### Android Java/Kotlin ```kotlin // Static reference 가 Activity: object MyManager { var activity: Activity? = null } // Activity rotate = leak (옛 instance retained). // 해결: WeakReference. object MyManager { var activity: WeakReference? = null } ``` ### Memory profiler ``` - Chrome DevTools (JS). - Xcode Instruments (iOS). - Android Studio Profiler. - Java VisualVM / async-profiler. - Go pprof. - Rust valgrind / heaptrack. ``` → Leak 발견. ### Production memory ``` - Heap size limit (container OOM). - 매 user 별 budget. - GC pause 가 latency. - Memory pressure handling. ``` → [[Native_Memory_Pressure_iOS_Android]]. ### Rust 의 zero-cost ``` Compile-time check. - Runtime overhead 0. - Manual 보다 더 안전. → "Safety + performance" 의 답. ``` ### When GC? ``` Pros: - 매 dev 가 memory worry X. - Rapid development. - Cycle 자동. Cons: - Pause time. - Memory usage 큰 (overhead). - Predictability ↓ (real-time 안). → Most app = GC OK. Game / embedded / OS = manual / Rust. ``` ### Hybrid (Rust + GC language) ``` LLM agent: - Rust 의 fast core (vector search). - Python 의 logic (script). → Best of both. ``` ### Memory layout ``` SOA (Struct of Arrays): - 매 field 의 array. - Cache locality 가 좋음 (1 field 만 read). AOS (Array of Structs): - 매 struct 의 array. - 매 row 사용 시 좋음. → Use case 따라. ``` ### NUMA ``` Multi-socket server. - 매 socket 의 own memory. - Cross-socket 가 slow. → NUMA-aware allocation. ``` ### Memory mapped file (mmap) ```c int fd = open('big-file', O_RDONLY); char* data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); // File 가 memory 처럼. // OS 가 page (lazy). ``` → 큰 file 처리. ## 🤔 의사결정 기준 | Language | Memory | |---|---| | Rust | Ownership (compile-time) | | C++ | RAII + smart pointer | | Go | GC (concurrent) | | Java | G1 / ZGC | | Python | RC + cycle | | JS | V8 GC | | Swift | ARC + weak | | Kotlin | JVM GC | ## ❌ 안티패턴 - **Manual free 잊음**: leak. - **Cycle 의 ARC**: leak. - **Static reference 의 Activity**: leak. - **Closure 의 big object**: leak. - **GC tune 0 인지**: pause. - **Rust 가 Arc 가짜**: cycle = leak. ## 🤖 LLM 활용 힌트 - Rust ownership 가 modern. - GC 가 most app 의 OK. - Cycle 의 ARC / RC = weak. - Leak 가 흔한 (closure, listener, static). ## 🔗 관련 문서 - [[CS_LockFree_Atomic]] - [[Native_Memory_Pressure_iOS_Android]] - [[Perf_V8_Optimization]]