커널의 메모리 재할당

1. /proc/smaps — 프로세스 메모리 상세 분석

/proc/[pid]/maps의 확장판으로, 각 VMA(Virtual Memory Area)별 상세 메모리 통계 제공

핵심 필드

필드 의미

Size가상 주소 공간 크기 (top의 VIRT)
Rss실제 물리 메모리 점유량 (top의 RES)
Pss공유 비율 보정된 실질 메모리 비용
Shared_Clean공유 라이브러리 코드 — 언제든 해제 가능
Private_Dirty프로세스가 실제로 소유한 메모리 (힙, 스택, CoW 후 수정)
Swap스왑으로 내보내진 페이지 수
Anonymous파일 백킹 없는 익명 메모리 (malloc, 스택 등)

PSS가 중요한 이유

4개 프로세스가 400KB 공유 라이브러리 사용 시

RSS: 각 400KB → 합계 1600KB (과대계상)
PSS: 각 100KB → 합계  400KB (현실 반영)

실용 명령

# PSS 합산 (실질 메모리 사용량)
grep Pss /proc/$(pgrep nginx)/smaps | awk '{sum+=$2} END {print sum" kB"}'

# Private_Dirty 합산
grep Private_Dirty /proc/$(pgrep python3)/smaps | awk '{sum+=$2} END {print sum" kB"}'

# 전체 요약
cat /proc/$(pgrep bash)/smaps_rollup

2. 버디 시스템 (Buddy System)

커널이 물리 메모리의 외부 단편화를 방지하기 위해 사용하는 페이지 할당 메커니즘

구조

메모리를 2의 거듭제곱 크기 블록으로 관리, order별 free list 유지

order 0:  4KB
order 1:  8KB
order 2:  16KB
...
order 10: 4MB   (x86 최대)
order 11: 8MB   (Raspberry Pi — ARM은 더 큰 블록 지원)
cat /proc/buddyinfo
# Node 0, zone DMA  36  160  96  40  28  18  8  7  5  3  2  9
#                   ^   ^    ^
#                 order0  1   2 ...

할당 과정

12KB 요청 → 16KB(order 2) 필요
order 2 free 블록 있음? → 즉시 할당
없으면 → order 3(32KB)을 절반으로 분할
         16KB 할당 + 나머지 16KB는 버디로 free list에 반환

해제 및 합치기 (Coalescing) ← 핵심

16KB 블록 해제
  → 버디도 free? → 32KB로 합침
  → 그 버디도 free? → 64KB로 합침
  → 반복 → 큰 연속 블록 복원

버디 주소 계산: 버디 주소 = 블록 주소 XOR 블록 크기

한계 — 내부 단편화

요청: 5KB → 할당: 8KB → 낭비: 3KB

→ 보완하는 것이 슬럽 할당자(SLUB)

버디 시스템 vs 슬럽 할당자

버디 시스템 슬럽 할당자

관리 단위페이지 단위 (4KB~8MB)객체 단위 (수십~수백 바이트)
역할페이지 프레임 할당kmalloc, 커널 구조체 할당
단편화 방지외부 단편화내부 단편화
버디 시스템 → 슬럽 할당자 → kmalloc() → 커널 코드

3. buddyinfo와 메모리 지표 관계

일반 프로세스와 buddyinfo

프로세스 malloc() 소규모
  → glibc 힙에서 처리 → buddyinfo 변화 없음

힙이 부족해 커널에 새 페이지 요청 (brk/mmap)
  → 커널이 버디에서 페이지 꺼냄 → buddyinfo 차감

파일 읽기(페이지 캐시), 커널 내부 구조체 필요
  → 버디에서 직접 할당 → buddyinfo 차감
buddyinfo = 물리 메모리 여유분의 실시간 재고표

buddyinfo vs free vs meminfo 관계

buddyinfo 합산  ≈  MemFree          (당장 꺼낼 수 있는 물리 블록)
MemAvailable    =  MemFree + Cached + SReclaimable(일부)

항목 buddyinfo MemFree MemAvailable

버디 free 블록
페이지 캐시
슬럽 reclaimable
cat /proc/meminfo | grep -E "MemFree|MemAvailable|Cached|SReclaimable"

4. 페이지 캐시와 페이지 회수

커널의 메모리 활용 철학

남는 메모리는 페이지 캐시로 활용 → 파일 I/O 성능 향상
프로세스가 메모리 필요 시 → 페이지 캐시를 회수(reclaim) 해서 제공

페이지 회수 메커니즘

메커니즘 동작

kswapd백그라운드에서 미리 페이지 회수
직접 회수메모리 급부족 시 즉시 회수
OOM killer회수해도 부족하면 프로세스 강제 종료

5. vm.swappiness / vm.vfs_cache_pressure

vm.swappiness

메모리 부족 시 스왑을 얼마나 적극적으로 사용할 것인가

cat /proc/sys/vm/swappiness  # 기본값: 60

값 동작

0스왑 최소화 (OOM 위험 증가)
60기본값
100스왑 적극 사용
Raspberry Pi는 SD카드 수명·속도 문제로 낮게 설정 권장 (예: 10)

vm.vfs_cache_pressure

페이지 캐시 / inode / dentry 캐시를 얼마나 적극적으로 회수할 것인가

cat /proc/sys/vm/vfs_cache_pressure  # 기본값: 100

값 동작

0캐시 절대 안 버림 (메모리 누수 위험)
100기본값, 균형
200캐시 공격적으로 회수

둘의 관계

메모리 부족 시 커널의 선택지

① 익명 메모리(힙/스택) → 스왑으로   ← swappiness 조절
② 페이지 캐시/inode    → 회수        ← vfs_cache_pressure 조절

Raspberry Pi 권장 설정

sysctl vm.swappiness vm.vfs_cache_pressure

# 권장값
vm.swappiness = 10
vm.vfs_cache_pressure = 50

Read more

mybloodyvalentine 3집 loveless

마이블러디발렌타인의 정규 2집 loveless 엘피를 김밥레코즈에서 5만원가량의 금액으로 구매. 요건 평생 들어도 질리지않을거같아 바이닐로 구매했다. 물리적인 이슈가 발생하지않는 한 이제 스트리밍 플랫폼의 의존성없이 평생 청취 가능하다 내부 크레딧 개인적으로 빌린다 부처의 맥아리없는 보컬을 참 좋아한다. 바이닐 커버를 벗기면 평범하다 0:00 /0:12 1× 2집 loveless만큼 3집 mbv도 좋아해서 아마

By 권동혁