c24165b8bc
에이전트 8종(대화형/프로그래머 C·S/디자이너/설계자/기획자/QA/PD/PM)에게 [공통 기본 능력 + 롤별 Specialty] 2층으로 지식을 주입하기 위한 재분류. 문서 내용·포맷은 무수정, 폴더 이동만 (6,372개 문서 수 보존 확인). - Topic_Programming → Domain_Programming (내부 구조 보존) - Topic_Graphic → Domain_Design - Topic_Business → Domain_Product - Topic_General → Domain_General - _Common 신설: Math(구 Topic_Math_Specialty), Reasoning(구 General/From_Thinking & Reasoning), Reasoning_Creativity(구 General/From_창의성), Communication(Poetic_Blog_Writing + From_writing) - 타 도메인의 From_* 폴더는 유지 (출처 표기일 뿐, 이미 도메인에 맞게 분류된 문서) - 빈 폴더 정리 (memory/procedures) - 에이전트→폴더 매핑은 workspace의 .astra/agent-knowledge-map.json (9개 에이전트) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.0 KiB
6.0 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-gc-root | GC Root | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
GC Root
매 한 줄
"매 도달 가능성(reachability) 의 출발점". GC Root 는 garbage collector 가 live object 를 판별하기 위해 traversal 을 시작하는 reference set. 매 root 에서 도달 불가능한 object 는 collectible 로 marking 된다. JVM, .NET CLR, V8, Go runtime 모두 같은 개념을 공유한다.
매 핵심
매 GC Root 종류 (HotSpot 기준)
- Stack reference: 매 thread 의 local variable / parameter / operand stack.
- Static field: 매 loaded class 의 static reference.
- JNI local/global: 매 native code 가 hold 한 reference.
- Active thread: 매 살아있는
Threadobject 자체. - Class metadata: 매 ClassLoader, Class object (Metaspace).
- Synchronization monitor: 매
synchronized로 lock 된 object. - Weak/Soft/Phantom 제외: 매 reachability 약한 reference 는 root 가 아님.
매 Reachability tier
- Strongly reachable: root 에서 strong ref 만으로 도달 → never collected.
- Softly reachable: SoftReference 로만 도달 → 매 memory pressure 시 collect.
- Weakly reachable: WeakReference 만 → 매 next GC cycle 에 collect.
- Phantom reachable: PhantomReference → enqueue 후 cleaning.
- Unreachable: → collectible.
매 응용
- Memory leak 진단 (heap dump → root path 추적).
- Escape analysis (root 도달 안 되는 local → stack alloc).
- Concurrent GC 의 root scanning (ZGC, Shenandoah, G1 의 phase 1).
💻 패턴
1. Heap dump 에서 root path 찾기 (Eclipse MAT / jhat)
# JVM heap dump 생성
jcmd <pid> GC.heap_dump /tmp/heap.hprof
# Eclipse MAT CLI 로 leak suspects 분석
./MemoryAnalyzer -consoleLog -application org.eclipse.mat.api.parse \
/tmp/heap.hprof org.eclipse.mat.api:suspects
2. JFR 로 GC root 통계 수집 (JDK 21+)
java -XX:StartFlightRecording=duration=60s,filename=app.jfr,settings=profile \
-XX:+UseZGC -Xmx4g -jar app.jar
jfr print --events GarbageCollection,GCReferenceStatistics app.jfr
3. WeakReference 로 root 진입 회피
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
// Cache 가 GC root 가 되어 leak 발생하는 anti-pattern 회피
public class Cache<K, V> {
private final WeakHashMap<K, V> map = new WeakHashMap<>();
public void put(K key, V value) { map.put(key, value); }
public V get(K key) { return map.get(key); }
// key 가 외부에서 strong ref 사라지면 entry 자동 제거
}
4. ThreadLocal leak 회피 (매 typical root leak)
public class RequestContext {
private static final ThreadLocal<UserSession> CTX = new ThreadLocal<>();
public static void set(UserSession s) { CTX.set(s); }
public static UserSession get() { return CTX.get(); }
// 매 critical: thread pool 환경에서 반드시 remove() 호출
public static void clear() { CTX.remove(); }
}
// Servlet filter 에서:
try {
RequestContext.set(session);
chain.doFilter(req, res);
} finally {
RequestContext.clear(); // 매 root reference 끊기
}
5. JNI global ref 정리 (native code 가 GC root)
// JNI: global ref 는 명시적으로 free 해야 함
jobject globalRef = (*env)->NewGlobalRef(env, localObj);
// ... 사용 ...
(*env)->DeleteGlobalRef(env, globalRef); // 매 빠뜨리면 영구 leak
6. Static field 로 의도된 long-lived root
object AppMetrics { // 매 Kotlin object → static singleton → GC root
private val counter = AtomicLong(0)
fun increment() = counter.incrementAndGet()
fun snapshot() = counter.get()
}
7. ZGC / Shenandoah concurrent root scanning 활성화
# JDK 21+: ZGC generational
java -XX:+UseZGC -XX:+ZGenerational \
-XX:SoftMaxHeapSize=8g -Xmx16g -jar app.jar
# Shenandoah
java -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -jar app.jar
8. Async profiler 로 allocation root 찾기
./profiler.sh -e alloc -d 60 -f alloc.html <pid>
# 매 flamegraph 에서 root → leaking site path 시각화
매 결정 기준
| 상황 | Approach |
|---|---|
| Long-lived cache | WeakHashMap / Caffeine weakKeys() |
| Per-request state in pool | ThreadLocal + try/finally remove() |
| Native handle wrapping | Cleaner (java.lang.ref.Cleaner, JDK 9+) |
| Listener registration | WeakReference 로 listener wrap |
| 매 short-lived burst alloc | 매 그냥 strong ref + young gen 의존 |
기본값: 매 strong ref + escape analysis 신뢰. WeakReference 는 매 진짜 leak 패턴 (cache, listener, ThreadLocal in pool) 에만.
🔗 Graph
- 부모: Garbage Collection
- 응용: Memory Leak Detection
🤖 LLM 활용
언제: heap dump 의 leak suspect 해석, root path 의 의미 설명, ThreadLocal/static leak pattern detection. 언제 X: 매 production 의 실제 GC tuning (real profiling 데이터 없이 추측 X).
❌ 안티패턴
- Static collection 무한 grow:
static List에 매 add 만 하고 remove 안 함 → 영구 root. - ThreadLocal in pool no remove: 매 thread 재사용 시 이전 request data 가 root 로 남음.
- JNI GlobalRef leak: native 에서
DeleteGlobalRef누락. - Anonymous inner class capture:
new Runnable() {}가 outerthis를 capture → outer 가 root 에 매달림. - Listener 등록 후 unregister 안 함: 매 EventBus, Observer 패턴의 classic leak.
🧪 검증 / 중복
- Verified (OpenJDK HotSpot source, JEP 376/439, Eclipse MAT docs).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — GC root taxonomy + leak 진단 패턴 |