9148c358d0
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
5.5 KiB
5.5 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-메모리-누수-memory-leaks | 메모리 누수(Memory Leaks) | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
메모리 누수(Memory Leaks)
매 한 줄
"매 alive 인데 매 unused, 매 unused 인데 매 free X". 매 manual mem (C/C++) 의 free 누락, 매 GC mem (Java/JS) 의 unintended retention. 매 long-running process 의 매 가장 흔한 incident, 매 2026 도구는 매 ASan/heaptrack/V8 heap snapshot/JFR + AI-assisted root cause.
매 핵심
매 두 의미
- 매 Manual leak: 매 free X — 매 OS 가 매 process 종료 시 매 회수.
- 매 GC leak: 매 root 에서 매 reachable 이지만 매 logically dead — 매 unintended retention.
매 흔한 원인
- 매 Cache 의 unbounded growth.
- 매 Listener / observer 의 unsubscribe 누락.
- 매 Closure 의 unintended capture (JS).
- 매 Static collection (HashMap) 의 누적.
- 매 ThreadLocal 의 cleanup 누락 (JVM/web).
- 매 Native handle (file/socket) 의 close 누락.
- 매 Circular ref + RC (Python before GC, Swift, ObjC ARC).
매 detection 의 axes
- 매 Symptom: 매 RSS 증가, 매 OOM, 매 GC 빈도 ↑, 매 latency drift.
- 매 Tool: 매 sampling profiler, 매 heap snapshot, 매 allocation tracking.
패턴
C++ Valgrind
g++ -g -O0 main.cpp -o app
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./app
# 매 "definitely lost" 의 우선 fix
C++ AddressSanitizer + LeakSanitizer
g++ -fsanitize=address,leak -g main.cpp -o app
ASAN_OPTIONS=detect_leaks=1 ./app
C++ RAII (matter of design)
class FileHandle {
FILE* f;
public:
explicit FileHandle(const char* p) : f(fopen(p, "r")) {}
~FileHandle() { if (f) fclose(f); }
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
};
// 매 std::unique_ptr / std::shared_ptr 가 매 default
JS — listener 누락
// 매 BAD — node 가 떠도 listener 가 retain
function attach(el) {
const handler = () => doStuff(el);
el.addEventListener("click", handler);
}
// 매 GOOD
function attach(el) {
const handler = () => doStuff(el);
el.addEventListener("click", handler);
return () => el.removeEventListener("click", handler);
}
JS — closure 의 unintended capture
// 매 BAD — 매 huge 가 매 outer scope 에 retained
function setup() {
const huge = new Array(1e7).fill(0);
const small = huge[0];
return () => small;
}
// 매 GOOD
function setup() {
const small = (() => {
const huge = new Array(1e7).fill(0);
return huge[0];
})();
return () => small;
}
Java — static map leak
// 매 BAD
public class Cache {
static final Map<Key, Value> M = new HashMap<>();
}
// 매 GOOD — Caffeine size cap + eviction
import com.github.benmanes.caffeine.cache.*;
Cache<Key, Value> c = Caffeine.newBuilder()
.maximumSize(10_000).expireAfterWrite(Duration.ofMinutes(10)).build();
Java heap dump + MAT
jcmd <pid> GC.heap_dump /tmp/heap.hprof
# 매 Eclipse MAT 에서 dominator tree / leak suspect
Chrome DevTools — heap snapshot diff
1. baseline snapshot
2. suspect action 반복 (e.g. open/close modal x10)
3. second snapshot
4. "Comparison" mode, 매 retained 증가 식별
5. retainer chain 의 root 추적
Python tracemalloc
import tracemalloc
tracemalloc.start(25)
snap1 = tracemalloc.take_snapshot()
# ... 매 action 반복 ...
snap2 = tracemalloc.take_snapshot()
for stat in snap2.compare_to(snap1, 'lineno')[:10]:
print(stat)
Linux heaptrack (C/C++ low-overhead)
heaptrack ./app
heaptrack_gui heaptrack.app.<pid>.gz
매 결정 기준
| Stack | Tool |
|---|---|
| C/C++ dev | ASan + LeakSanitizer |
| C/C++ prod | heaptrack / jemalloc profiler |
| Java | JFR + heap dump + MAT |
| Node.js | --inspect + Chrome heap snapshot |
| Browser | DevTools Memory tab |
| Python | tracemalloc / objgraph / memray |
| Go | pprof (heap profile) |
기본값: 매 first symptom = RSS chart, 매 second = heap snapshot diff, 매 third = retainer/dominator analysis.
Graph
- 부모: Memory Management · Performance
- 응용: Cache Eviction · WeakRef
- Adjacent: Garbage Collection · Reference Counting · RAII · OOM
LLM 활용
언제: 매 leak 패턴 식별, 매 fix 제안 (RAII, weak ref, eviction policy), 매 heap dump 분석 hint. 언제 X: 매 production heap 의 직접 access, 매 sensitive customer data dump.
안티패턴
- 매 OOM 시 -Xmx ↑: 매 leak 을 매 늦출 뿐.
- 매 try/finally 없는 close: 매 try-with-resources / RAII / context manager 사용.
- 매 Strong cache without eviction: Caffeine / LRU.
- 매 Listener pattern 의 no unsubscribe: weakRef / dispose.
- 매 GC tuning 으로 leak 감추기: root cause X.
검증 / 중복
- Verified: Valgrind manual, ASan docs, V8 blog, JFR docs, tracemalloc PEP, heaptrack docs.
- 신뢰도 A.
Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — leak detection per-stack/anti-patterns/RAII 작성 |