Files
2nd/10_Wiki/Topics/Coding/CS_Memory_Management_Patterns.md
T
2026-05-10 22:08:15 +09:00

7.4 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
cs-memory-management-patterns Memory Management — GC / arena / RC / ownership Coding draft B conceptual 2026-05-09 2026-05-09
cs
memory
vibe-coding
language applicable_to
C++ / Rust
CS
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

int* arr = malloc(100 * sizeof(int));
// 사용.
free(arr);

→ Forget = leak. Double-free = crash.

C++ RAII

{
  std::vector<int> v(100);
  // 사용.
}  // 자동 destroy (RAII).

→ Scope 끝 = destructor.

Smart pointer (C++)

auto p = std::make_unique<MyClass>();   // exclusive.
auto s = std::make_shared<MyClass>();   // shared (RC).
auto w = std::weak_ptr<MyClass>(s);     // non-owning.

→ unique = single owner. shared = ref count. weak = no own (cycle 방지).

Rust ownership

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

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

use std::rc::Rc;

let a = Rc::new(MyData);
let b = a.clone();  // count = 2.
// Drop = count--.

→ Single-threaded.

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

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.
GOGC=200  # GC 가 less frequent (memory ↑).

Python ref count + GC

Ref count + cycle detector.
- 매 object 가 count.
- Count 0 = free.
- Cycle = generational GC.
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

// ❌ Closure 가 외부 변수 retain
function setup() {
    const big = new Array(1000000);
    return () => console.log('hi');  // big 도 retain.
}

const fn = setup();
// big 가 GC 안.
// ❌ 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).
use bumpalo::Bump;

let arena = Bump::new();
let v = arena.alloc(MyData { ... });
// ... 매 frame 의 alloc.

// 매 frame 끝:
drop(arena);  // 모든 free.

→ Game engine 친화.

Pool allocation

struct Pool<T> {
    items: Vec<T>,
    free: Vec<usize>,
}

impl<T> Pool<T> {
    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

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)

const cache = new WeakMap<object, string>();
cache.set(user, 'cached value');

// User 가 GC 됨 = cache entry 도.

→ Memory leak 방지.

iOS / macOS ARC

class Person {
    var partner: Person?
}

let alice = Person()
let bob = Person()
alice.partner = bob   // strong.
bob.partner = alice   // strong → cycle.
// → Memory leak.
class Person {
    weak var partner: Person?  // weak — no retain.
}

Android Java/Kotlin

// Static reference 가 Activity:
object MyManager {
    var activity: Activity? = null
}
// Activity rotate = leak (옛 instance retained).

// 해결: WeakReference.
object MyManager {
    var activity: WeakReference<Activity>? = 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)

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).

🔗 관련 문서