앞 글에서 /proc/smaps로 메모리를 분석하는 방법을 봤다.
- RSS가 뭔지
- anon인지 file인지
- 실제로 어떤 메모리가 늘고 있는지
이제 어느 정도 “상태”는 볼 수 있게 된다.
그런데 여기서 한 번 더 막힌다.
“이게 왜 늘고 있는지는 어떻게 알지?”
smaps는 결과를 보여줄 뿐이다.
원인을 알려주지는 않는다.
예를 들어:
- heap이 늘어나고 있는 건 알겠는데
- 어떤 코드가 malloc을 계속 호출하는지는 모른다
이걸 보려면 결국 실행 흐름을 따라가야 한다.
여기서 eBPF가 등장한다
이 시점에서 자연스럽게 나오는 게 eBPF다.
이걸 처음 보면 좀 과하게 느껴진다.
“커널에서 코드 실행? 이걸 왜 써야 하지?”
그런데 지금 상황을 보면 이유가 명확하다.
우리가 알고 싶은 것
- 언제 malloc이 호출되는지
- 얼마나 할당되는지
- 어디서 호출되는지
- free는 제대로 되고 있는지
이걸 기존 방식으로 보면 문제가 있다.
기존 방법은 한계가 있다
printf
코드에 직접 찍는다.
→ 코드 수정 필요
→ 운영 환경에서 사용 어려움
strace
strace -p <pid>
→ 시스템 콜만 보임
→ malloc 같은 내부 동작은 안 보임
→ 오버헤드 큼
perf
→ 일부는 보이지만 제한적
→ 깊은 메모리 흐름은 어렵다
그래서 필요한 게 “중간에서 보는 방법”이다
여기서 핵심은 이거다.
코드를 바꾸지 않고, 실행 흐름을 중간에서 관찰하고 싶다
이걸 가능하게 해주는 게 eBPF다.
eBPF를 어떻게 쓰는지 감 잡기
eBPF를 너무 어렵게 생각할 필요 없다.
개념만 보면 단순하다.
특정 함수 호출
↓
hook
↓
eBPF 코드 실행
↓
정보 수집
즉,
“이 함수가 호출될 때마다 내가 만든 코드도 같이 실행해줘”
이게 핵심이다.
malloc을 추적한다는 건 무슨 의미일까
이걸 실제로 보면 이런 식이다.
목표
- malloc 호출 횟수
- 할당 크기
- 호출 위치
방법
malloc 함수에 hook
↓
호출될 때마다 기록
예를 보면 이해가 빠르다
bpftrace 같은 도구를 쓰면 이런 식으로 볼 수 있다.
bpftrace -e 'uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc { @[ustack] = count(); }'
이게 하는 일은 단순하다.
- malloc이 호출될 때마다
- 어떤 함수에서 왔는지 기록한다
결과는 이런 식으로 나온다.
main → process_request → malloc
worker → parse → malloc
👉 즉,
어디서 메모리가 생성되는지 바로 보인다
free도 같이 보면 더 명확해진다
malloc만 보면 부족하다.
같이 봐야 하는 것
- malloc
- free
그래야 알 수 있다.
할당만 많고 해제가 없나?
이걸 보면 이런 패턴이 나온다.
정상
malloc → free → malloc → free
문제
malloc → malloc → malloc → ...
( free 없음 )
👉 이건 거의 메모리 누수 패턴이다.
여기서 중요한 포인트
eBPF의 진짜 장점은 이거다.
1. 코드 수정 없음
- 운영 환경 그대로 분석 가능
2. 낮은 오버헤드
- 실시간 추적 가능
3. 원하는 지점만 관찰
- 특정 함수만
- 특정 조건만
👉 그래서 “관찰 도구”로 강력하다
smaps + eBPF를 같이 보면 완성된다
이제 퍼즐이 맞춰진다.
smaps
→ “무슨 메모리가 늘었는지”
eBPF
→ “왜 늘었는지”
👉 둘을 같이 보면:
문제 원인까지 연결된다
여기까지 오면 보이는 것
이제 이런 식으로 생각하게 된다.
- RSS 증가 → smaps로 분해
- anon 증가 → eBPF로 malloc 추적
- 특정 함수 발견 → 코드 분석
👉 이게 실제 성능 분석 흐름이다.
다음으로 이어지는 질문
여기까지 오면 이런 생각이 든다.
“eBPF가 이렇게 강력한데, 이거 위험한 거 아닌가?”
맞는 질문이다.
한 줄 정리
eBPF는 커널 내부에서 특정 함수 호출을 가로채 실행 흐름을 관찰할 수 있게 해주며, smaps와 함께 사용하면 메모리 문제의 원인을 추적할 수 있다.
'프로그래밍공부(Programming Study) > CS-운영체제(OS)' 카테고리의 다른 글
| eBPF는 내부적으로 어떻게 동작할까 (0) | 2026.04.08 |
|---|---|
| eBPF는 왜 안전한가 (그리고 언제 위험한가) (0) | 2026.04.07 |
| /proc/smaps로 메모리를 제대로 분석하는 방법 (0) | 2026.04.05 |
| free를 했는데 왜 RSS는 줄어들지 않을까 (0) | 2026.04.04 |
| O(1)인데 왜 느려질까 (메모리 성능의 진짜 문제) (0) | 2026.04.03 |
댓글