Files
2nd/10_Wiki/Topics/Architecture/Garbage_Collection.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

190 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: wiki-2026-0508-garbage-collection
title: Garbage Collection
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [GC, Garbage Collector, Memory Management]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [runtime, memory, performance, vm]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: java
framework: jvm
---
# Garbage Collection
## 매 한 줄
> **"매 unreachable memory를 자동으로 reclaim한다"**. 매 GC는 manual malloc/free의 cognitive burden을 제거 — McCarthy의 Lisp(1959)에서 시작, modern V8/HotSpot/Go의 generational + concurrent collector로 evolution. 2026 trade-off는 매 throughput vs latency vs memory overhead.
## 매 핵심
### 매 Algorithm 분류
- **Mark-and-sweep**: 매 reachable mark → unreachable sweep (fragmentation)
- **Copying (semi-space)**: 매 live obj 새 space로 copy (50% memory waste)
- **Mark-compact**: 매 mark 후 live obj 한쪽 끝으로 compact
- **Reference counting**: 매 ref count 0 즉시 free (cycle 문제)
### 매 Generational Hypothesis
- **매 most objects die young**: 매 short-lived 95%+
- **Young gen** (eden + survivor): 매 frequent, fast minor GC
- **Old gen** (tenured): 매 infrequent, expensive major GC
- **매 write barrier**: old → young reference tracking
### 매 응용
1. JVM (G1, ZGC, Shenandoah) — sub-ms pause.
2. V8 (Orinoco) — concurrent + parallel + incremental.
3. Go (tricolor concurrent) — sub-ms STW pause.
4. .NET (Server GC, regions) — generational + LOH.
## 💻 패턴
### JVM ZGC 설정 (sub-ms pause)
```bash
java -XX:+UseZGC \
-XX:+ZGenerational \
-Xmx16g \
-XX:SoftMaxHeapSize=14g \
-jar app.jar
```
### Go GC tuning
```go
import "runtime/debug"
func init() {
// 매 GOGC=100 default — 100% growth 시 trigger
debug.SetGCPercent(50) // 매 lower = more frequent, less memory
// 매 hard memory limit (Go 1.19+)
debug.SetMemoryLimit(8 << 30) // 매 8GB
}
// 매 manual hint after large alloc
runtime.GC()
```
### V8 Heap snapshot (Node.js)
```javascript
const v8 = require('v8');
const fs = require('fs');
// 매 heap snapshot for leak analysis
const snapshot = v8.writeHeapSnapshot();
console.log(`Heap snapshot: ${snapshot}`);
// 매 heap statistics
console.log(v8.getHeapStatistics());
// { total_heap_size, used_heap_size, heap_size_limit, ... }
```
### Reference cycle break (Python)
```python
import weakref
class Parent:
def __init__(self):
self.children = []
class Child:
def __init__(self, parent):
# 매 strong cycle: parent ↔ child → leak
# self.parent = parent
# 매 fix: weakref
self.parent = weakref.ref(parent)
def get_parent(self):
return self.parent() # 매 None if collected
```
### Object pooling (avoid GC pressure)
```csharp
public class BulletPool
{
private readonly Stack<Bullet> pool = new();
public Bullet Rent()
{
if (pool.Count > 0) return pool.Pop();
return new Bullet();
}
public void Return(Bullet b)
{
b.Reset();
pool.Push(b);
}
}
// 매 hot path에서 alloc 회피 → minor GC 감소
```
### Tricolor marking (concept, Go-style)
```go
// 매 white = unscanned, gray = in queue, black = scanned
// invariant: 매 black은 white를 직접 reference 안 함
// write barrier로 enforce:
func writeBarrier(slot **Object, ptr *Object) {
if isBlack(slot) && isWhite(ptr) {
markGray(ptr) // 매 promote to gray
}
*slot = ptr
}
```
### .NET Span<T> (stack alloc, no GC)
```csharp
public int SumDigits(int n)
{
Span<int> digits = stackalloc int[16];
int i = 0;
while (n > 0) { digits[i++] = n % 10; n /= 10; }
int sum = 0;
for (int j = 0; j < i; j++) sum += digits[j];
return sum; // 매 zero heap allocation
}
```
## 매 결정 기준
| 상황 | GC choice |
|---|---|
| Low-latency trading (JVM) | ZGC / Shenandoah (sub-ms pause) |
| Throughput batch (JVM) | Parallel GC |
| Game engine (managed) | Object pooling + GC.Collect at safe points |
| Real-time embedded | Manual memory or Rust (no GC) |
| Server-side Go | Default tricolor + GOGC tuning |
**기본값**: 매 modern runtime의 default GC. 매 measure first (allocation profiler), tune later.
## 🔗 Graph
- 부모: [[Memory Management]]
- 변형: [[Reference Counting]]
- 응용: [[JVM]] · [[V8]]
- Adjacent: [[ARC]]
## 🤖 LLM 활용
**언제**: 매 GC pause 분석, allocation hotspot 식별, runtime flag tuning 추천.
**언제 X**: 매 Rust/C/C++ — GC 없음. 매 hard real-time — non-deterministic pause unacceptable.
## ❌ 안티패턴
- **Calling GC.Collect() 빈번**: 매 fragmentation + throughput 손실.
- **Finalizer 의존**: 매 non-deterministic, GC overhead 증가 → IDisposable 사용.
- **Large object heap thrash**: 매 LOH (.NET) 매번 alloc → fragmentation.
- **String concat in loop**: 매 immutable string × N alloc → StringBuilder 사용.
## 🧪 검증 / 중복
- Verified (Jones, Hosking, Moss, "The Garbage Collection Handbook", 2nd ed., 2023).
- Verified (Oracle ZGC docs, OpenJDK).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — generational GC + V8/Go/JVM modern collectors |