Linux free 읽는 법: available·page cache·slab·dentry 구분하기

반응형

Linux에서 메모리 여유를 빠르게 판단할 때는 free 열보다 available 열을 먼저 본다. 파일 캐시와 회수 가능한 커널 캐시는 필요할 때 애플리케이션에 돌려줄 수 있기 때문이다. Slab이 크다면 SReclaimableSUnreclaim을 나누고, 그다음 slabtop에서 dentry 같은 개별 커널 객체를 확인한다.

예전 글에서는 SReclaimable을 “주로 dentry/inode cache”라고 묶고 /proc/meminfo만으로 dentry 크기를 확인할 수 있는 것처럼 적었다. 정확하지 않았다. SReclaimable은 여러 회수 가능한 slab 캐시의 합이고, dentry 하나의 크기는 slabtop이나 /proc/slabinfo에서 따로 봐야 한다.

free -h에서 먼저 볼 값

free -h

대표 출력 형식은 다음과 같다.

               total        used        free      shared  buff/cache   available
Mem:            31Gi        12Gi       1.2Gi       900Mi        18Gi        17Gi
Swap:          8.0Gi       512Mi       7.5Gi
의미 해석할 때 주의할 점
total 커널이 사용할 수 있는 전체 메모리 장착된 RAM과 조금 다를 수 있다.
used 사용 중으로 계산된 메모리 procps 버전에 따라 계산식이 달라질 수 있다.
free 아무 용도로도 쓰이지 않는 메모리 작다는 이유만으로 부족하다고 판단하지 않는다.
buff/cache 버퍼와 페이지 캐시, 일부 회수 가능 slab 필요하면 상당 부분 회수할 수 있다.
available 스왑 없이 새 작업에 쓸 수 있다고 추정한 메모리 현재 여유를 볼 때 가장 실용적인 첫 지표다.

Linux 커널은 MemAvailableMemFree, 파일 LRU, SReclaimable, zone low watermark 등을 바탕으로 추정한다. 회수 가능하다고 표시된 메모리도 전부 즉시 회수할 수 있는 것은 아니라는 점까지 계산에 반영한다.

macOS의 명령과 비교하려면 macOS에서 free 대신 메모리 확인하는 법을 참고할 수 있다.

page cache와 slab cache는 무엇이 다른가

둘 다 성능을 위해 메모리를 쓰지만 저장하는 대상이 다르다.

  • page cache는 디스크에서 읽은 파일 내용을 메모리에 보관한다.
  • slab cache는 dentry, inode, 네트워크 버퍼 등 커널 내부 객체를 보관한다.
  • dentry cache는 경로 이름을 inode와 연결하는 VFS 객체를 재사용해 경로 탐색 비용을 줄인다.

freebuff/cache는 이 메모리들을 한눈에 보는 요약이다. 정확한 원인을 찾으려면 /proc/meminfo와 slab별 통계로 내려가야 한다.

/proc/meminfo에서 slab을 나눠 보기

grep -E '^(MemAvailable|Buffers|Cached|Slab|SReclaimable|SUnreclaim):' /proc/meminfo
MemAvailable:   17823456 kB
Buffers:          123456 kB
Cached:         10485760 kB
Slab:            2097152 kB
SReclaimable:    1572864 kB
SUnreclaim:       524288 kB
  • Slab: 커널 내부 데이터 구조 캐시의 전체 크기
  • SReclaimable: 메모리 압박이 생기면 커널이 회수를 시도할 수 있는 부분
  • SUnreclaim: 메모리 압박에도 회수할 수 없는 부분

중요한 관계는 다음과 같다.

Slab ≈ SReclaimable + SUnreclaim

SReclaimable이 크다고 곧바로 누수는 아니다. 파일을 많이 탐색했거나 컨테이너 이미지처럼 작은 파일을 대량으로 다룬 뒤 dentry와 inode 캐시가 커질 수 있다. 반대로 SUnreclaim이 계속 증가하고 메모리 압박도 함께 커진다면 커널 객체 누수나 특정 서브시스템을 의심할 근거가 된다.

dentry가 실제로 큰지 확인하기

요약이 아니라 개별 slab 캐시를 보려면 slabtop을 사용한다.

sudo slabtop -o

-o는 한 번 출력하고 종료한다. 출력에서 dentry, inode_cache, 파일시스템별 inode 캐시와 kmalloc-* 항목의 객체 수와 캐시 크기를 비교한다. 권한 정책이나 컨테이너 환경에 따라 /proc/slabinfo 접근이 제한될 수 있다.

dentry만 빠르게 찾는 예시는 다음과 같다.

sudo awk '$1 == "dentry" { print }' /proc/slabinfo

SReclaimable 전체를 dentry 크기로 부르면 안 되는 이유가 여기 있다. 이 값에는 inode와 다른 회수 가능한 커널 캐시도 함께 들어간다.

숫자가 클 때의 진단 순서

  1. free -h에서 available과 swap 사용량을 본다.
  2. vmstat 1si·so가 계속 발생하는지 확인한다.
  3. /proc/meminfo에서 page cache와 slab, SReclaimable·SUnreclaim을 나눈다.
  4. slab이 원인이라면 slabtop -o에서 큰 캐시를 찾는다.
  5. 애플리케이션 메모리인지 커널 메모리인지 구분한 뒤 다음 도구를 고른다.

운영 중인 서버에서는 캐시를 강제로 비우기 전에 이 순서를 거치는 편이 안전하다. drop_caches는 원인을 해결하지 않고 성능에 필요한 캐시까지 버릴 수 있다. 전체 분석 흐름은 실제 메모리 문제를 분석하는 순서, 애플리케이션 쪽 할당 구조는 malloc이 내부에서 메모리를 관리하는 방식으로 이어서 볼 수 있다.

참고 자료

반응형
KEEP READING
카테고리 전체 보기 →

댓글