---
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<int> v(100);
  // 사용.
}  // 자동 destroy (RAII).
```

→ Scope 끝 = destructor.

### Smart pointer (C++)
```cpp
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
```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<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
```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<object, string>();
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<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)
```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]]
