버퍼와 캐시 | /proc/meminfo
1. free -m — 버퍼와 캐시
total used free shared buff/cache available
Mem: 3900 1200 300 150 2400 2300
항목 설명
| Buffers | 블록 디바이스 메타데이터 버퍼 (inode, 디렉토리 등) |
| Cached | 파일 데이터 Page Cache |
| available | 실제로 사용 가능한 메모리 (캐시 회수분 포함) |
buff/cache 가 높아도 메모리 부족이 아님 — 커널이 자발적으로 채운 것이며, 필요 시 즉시 회수됨
메모리 여유 판단 기준 = available
2. /proc/meminfo — 상세 메모리 정보
free -m 은 요약본, /proc/meminfo 는 커널의 전체 메모리 원장
주요 항목
항목 설명
| MemTotal | 전체 물리 RAM |
| MemFree | 순수 빈 메모리 |
| MemAvailable | 실질 사용 가능 메모리 |
| Buffers | 블록 메타데이터 버퍼 |
| Cached | 파일 Page Cache |
| Active | 최근 사용됨 → 회수 후순위 |
| Inactive | 최근 미사용 → 회수 우선순위 |
| Slab | 커널 자료구조용 메모리 |
| SReclaimable | 회수 가능한 Slab (inode/dentry 캐시) |
| SUnreclaim | 회수 불가 Slab |
# 핵심 항목만 확인
grep -E "MemTotal|MemAvailable|Buffers|^Cached|Slab|SReclaimable" /proc/meminfo
3. 블록 I/O 핵심 함수
bio_init() — bio 구조체 초기화
- bio = 커널이 블록 디바이스에 I/O 요청을 보낼 때 사용하는 기본 단위
- 어느 디바이스에, 어떤 방향(READ/WRITE)으로 I/O할지 설정
- 현재 커널의 주력 방식
bio
├── bi_bdev → 대상 블록 디바이스
├── bi_opf → READ / WRITE / FLUSH
├── bi_iter → 현재 진행 위치
└── bi_io_vec[] → 실제 데이터 페이지 목록
__getblk() — 버퍼 헤드 조회/할당
- 특정 블록 번호에 대응하는 buffer_head 를 page cache에서 찾거나 새로 할당
- 아직 디스크 읽기는 하지 않음 (자리 확보만)
- 파일시스템 메타데이터 전용 (레거시 방식)
buffer_head vs bio
buffer_head bio
| 단위 | 단일 블록 | 여러 페이지 묶음 |
| 용도 | 파일시스템 메타데이터 | 일반 데이터 I/O |
| 레거시 여부 | 오래된 방식 | 현재 주력 |
| 대표 함수 | __getblk() | bio_alloc() / bio_init() |
전체 흐름
파일시스템 (ext4 등)
├─ 메타데이터 I/O → __getblk() → buffer_head → submit_bh()
└─ 데이터 I/O → bio_alloc() → bio_init() → submit_bio()
│
블록 I/O 스케줄러
│
디바이스 드라이버 → 실제 디스크
4. Active / Inactive 페이지
개념
Active = 최근에 썼다 → 건드리지 마
Inactive = 오래 안 썼다 → 필요하면 회수할게
이동 흐름
페이지 할당 → Inactive
│
접근 2회
│
Active
│
메모리 압박 발생 (kswapd 깨어남)
│
Active → Inactive → 회수(reclaim)
⚠️ Active → Inactive 강등은 시간 기반이 아님
메모리 압박(memory pressure) 이벤트 가 발생해야 kswapd 가 shrink_active_list() 를 실행
anon vs file
anon (익명) file
| 예시 | 프로세스 힙/스택, malloc() | 파일 캐시, read(), mmap() |
| 파일 연결 | ❌ | ✅ |
| 캐시 여부 | ❌ | ✅ (Page Cache) |
| 회수 시 | Swap에 써야 함 | 그냥 버림 (디스크 원본 있음) |
회수 우선순위
회수 쉬움 ◀──────────────────────────▶ 회수 어려움
Inactive(file) → Inactive(anon) → Active(file) → Active(anon)
5. LRU 리스트
Active/Inactive 경계는 커널의 LRU (Least Recently Used) 리스트 로 관리
LRU_INACTIVE_ANON ←→ LRU_ACTIVE_ANON
LRU_INACTIVE_FILE ←→ LRU_ACTIVE_FILE
/proc/meminfo 매핑
meminfo 항목 LRU 리스트
| Active(anon) | LRU_ACTIVE_ANON |
| Inactive(anon) | LRU_INACTIVE_ANON |
| Active(file) | LRU_ACTIVE_FILE |
| Inactive(file) | LRU_INACTIVE_FILE |
PG_referenced / PG_active 플래그
플래그 의미
| PG_referenced | 최근에 한 번 접근됨 |
| PG_active | Active 리스트에 있음 |
첫 접근 → PG_referenced 세팅
두 번째 접근 → Active 리스트로 승격
오랫동안 미접근 → PG_referenced 클리어 → Inactive로 강등 (메모리 압박 시)
확인 명령어 모음
# 기본 메모리 상태
free -m
# 상세 메모리 정보
cat /proc/meminfo
# 핵심 항목만
grep -E "MemAvailable|Buffers|^Cached|Active|Inactive|Slab" /proc/meminfo
# 캐시 강제 비우기 (학습용)
echo 3 | sudo tee /proc/sys/vm/drop_caches