Skip to content

가비지 컬렉션 & 메모리 프로파일링 ​

누수를 막아 주는 가비지 컬렉션(GC)과 그 한계, 그리고 누수를 찾아내는 프로파일링 도구를 함께 정리했습니다.

가비지 컬렉션 (Garbage Collection) ​

비유: 자동 청소부 vs 수동 청소 ​

언어별 메모리 관리 방식:

C/C++ (수동)          Python/Java (자동 GC)
개발자가 직접 청소     청소부(GC)가 알아서 청소

malloc() → 할당       new Object() → 할당
...사용...            ...사용...
free()   → 해제 ✋    // 자동으로 해제됨 🤖
          ↑
       잊으면 누수!

GC가 있어도 누수가 생기는 경우 ​

python
# Python에서도 누수 가능한 패턴!
cache = []  # 전역 리스트

def 문제있는함수():
    data = [0] * (25 * 1024 * 1024)  # 25MB
    cache.append(data)  # 전역에 추가
    # GC가 있어도 cache가 참조 중이라 해제 못 함!
    # → 참조가 남아있으면 GC도 수거 불가

GC의 한계: 참조(Reference)가 남아있으면 수거 불가 → 이 문서에서 "가비지 컬렉션 개선" 권장사항이 나온 이유

메모리 프로파일링 도구 ​

누수를 찾는 도구들 ​

C/C++ 계열:
┌─────────────┬──────────────────────────────────┐
│  Valgrind   │ 메모리 접근 오류, 누수 탐지        │
│  AddressSan │ 컴파일 타임 메모리 오류 탐지       │
└─────────────┴──────────────────────────────────┘

Python 계열:
┌─────────────┬──────────────────────────────────┐
│  tracemalloc│ 메모리 할당 추적 (표준 라이브러리) │
│  memory_prof│ 라인별 메모리 사용량 측정          │
│  objgraph   │ 객체 참조 그래프 시각화            │
└─────────────┴──────────────────────────────────┘

# Python 예시
import tracemalloc
tracemalloc.start()

# ... 의심 코드 실행 ...

snapshot = tracemalloc.take_snapshot()
for stat in snapshot.statistics('lineno')[:5]:
    print(stat)  # 어느 줄에서 얼마나 할당했는지 출력

정리 ​

구분내용
C/C++개발자가 free() 로 직접 해제, 잊으면 누수
Python/JavaGC가 자동 해제, 단 참조가 남아 있으면 수거 불가
C/C++ 도구Valgrind, AddressSan
Python 도구tracemalloc, memory_prof, objgraph

출처: Codyssey-B1/B4-2