[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,427 @@
|
||||
---
|
||||
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]]
|
||||
Reference in New Issue
Block a user