26Y06o1

Young-Kyoo Kim·2026년 7월 6일

가능합니다. 오히려 이런 경우는 free의 Used를 구성하는 메모리를 항목별로 분해(Spectrum) 해서 봐야 원인을 찾을 수 있습니다.

질문에서 주신 상황을 정리하면

  • Total : 1TB
  • Used : 725GiB
  • Available : 281GiB
  • Buff/Cache : 171GiB
  • RSS 합 : 약 200GB
  • Slab : 약 70GB
  • memory.current(cgroup) : 약 410GB
  • HugePage 거의 없음
  • SHMEM 거의 없음

즉,

RSS(200)
+ Slab(70)
+ Buff/Cache(171)
-------------------
약 441GB

Used = 725GB

=> 약 280GB 정도가 어디 있는지 잘 안보이는 상태

이 정도 차이면 단순 page cache 문제가 아닐 가능성이 있습니다.

Linux에서는 Used 안에 생각보다 많은 항목이 포함됩니다.

Used

├── Anonymous Memory (RSS)
├── File Cache
├── Slab
│    ├── SReclaimable
│    └── SUnreclaim
├── Kernel Stack
├── Page Tables
├── Percpu
├── Vmalloc
├── BPF Maps
├── TCP Buffers
├── UDP Buffers
├── Dentry/Inode Cache
├── XArray
├── Zswap
├── CMA
├── Direct Map
├── Unevictable
├── Mlocked
├── tmpfs
├── cgroup charged pages
├── pinned pages
└── 기타 kernel allocator

특히 AIStor + DirectPV 환경에서 의심되는 것

개인적으로는 아래 순으로 의심합니다.

① Page Cache (삭제가 안되는 Dirty Page)

Cached
Dirty
Writeback

AIStor는 대용량 sequential IO를 수행합니다.

Dirty Page가 계속 유지되면

free에서는 Used 증가

RSS에는 안보임

이 현상이 발생합니다.

확인

grep -E 'Dirty|Writeback|Cached' /proc/meminfo

② Direct IO가 아닌 일반 buffered IO

DirectPV 자체는 DirectIO를 강제하지 않습니다.

Application이

O_DIRECT

로 열지 않으면

Page Cache

를 많이 사용할 수 있습니다.


③ Kernel Memory (Network)

AIStor + Cilium이면

skb
tcp buffers
xdp
bpf

등이 생각보다 커질 수 있습니다.

특히

sockstat

/proc/net/sockstat

/proc/net/sockstat6

를 봐야 합니다.


④ BPF Map Memory

Cilium은

bpffs

에 map을 유지합니다.

map이 매우 커질 수 있습니다.

확인

bpftool map show

그리고

bpftool map dump

보다는

bpftool map show

에서

bytes_memlock

를 보는 것이 중요합니다.


⑤ Page Tables

엄청난 mmap이 있으면

PageTables

가 수십 GB도 가능합니다.

grep PageTables /proc/meminfo

⑥ Kernel Stack

KernelStack

thread가 수십만개면 커질 수 있습니다.


⑦ Percpu

Percpu

⑧ Vmalloc

VmallocUsed

⑨ Unevictable

Unevictable

⑩ Cgroup memory accounting

질문에서

memory.current = 410GB

라고 하셨는데

RSS = 200GB

라면

memory.current

안에도

cache
slab
kernel memory

가 포함됩니다.

따라서

memory.stat

를 봐야 합니다.

cat memory.stat

Cilium Leak 가능성

가능성은 있습니다.

대표 사례는

① conntrack leak

cilium bpf ct list

혹은

bpftool map show

에서

cilium_ct4_global

가 매우 커짐.


② LB map leak

lb4_services

lb4_backends

lb_affinity

③ Endpoint map leak

endpoint map

④ Policy map leak

policy map

⑤ XDP buffer

특히

bpf.masquerade=true

사용 시

BPF map 증가 사례가 종종 보고됩니다.


제가 추천하는 분석 스크립트

이 스크립트 하나로

Used Memory Spectrum

처럼 보여주면 원인 파악이 훨씬 쉽습니다.

#!/bin/bash

MEMINFO=/proc/meminfo

get_mem() {
    awk -v key="$1" '$1==key":" {print $2}' $MEMINFO
}

TOTAL=$(get_mem MemTotal)
FREE=$(get_mem MemFree)
AVAIL=$(get_mem MemAvailable)

CACHE=$(get_mem Cached)
BUFFERS=$(get_mem Buffers)

SLAB=$(get_mem Slab)
SREC=$(get_mem SReclaimable)
SUNREC=$(get_mem SUnreclaim)

DIRTY=$(get_mem Dirty)
WRITEBACK=$(get_mem Writeback)

SHMEM=$(get_mem Shmem)

PGTABLE=$(get_mem PageTables)
KSTACK=$(get_mem KernelStack)
PERCPU=$(get_mem Percpu)

VMALLOC=$(get_mem VmallocUsed)

UNEVICT=$(get_mem Unevictable)
MLOCK=$(get_mem Mlocked)

ANON=$(get_mem AnonPages)
FILE=$(get_mem FilePages)

echo
echo "========= Memory Spectrum ========="

printf "%-25s %10.1f GB\n" "AnonPages"       "$(echo "$ANON/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "File Cache"      "$(echo "$CACHE/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Buffers"         "$(echo "$BUFFERS/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Slab"            "$(echo "$SLAB/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" " SReclaimable"   "$(echo "$SREC/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" " SUnreclaim"     "$(echo "$SUNREC/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Dirty"           "$(echo "$DIRTY/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Writeback"       "$(echo "$WRITEBACK/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Shmem"           "$(echo "$SHMEM/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "PageTables"      "$(echo "$PGTABLE/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "KernelStack"     "$(echo "$KSTACK/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Percpu"          "$(echo "$PERCPU/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Vmalloc"         "$(echo "$VMALLOC/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Unevictable"     "$(echo "$UNEVICT/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Mlocked"         "$(echo "$MLOCK/1024/1024" | bc -l)"

echo
echo "========== Totals =========="

printf "%-25s %10.1f GB\n" "Total"       "$(echo "$TOTAL/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Free"        "$(echo "$FREE/1024/1024" | bc -l)"
printf "%-25s %10.1f GB\n" "Available"   "$(echo "$AVAIL/1024/1024" | bc -l)"

USED=$((TOTAL-FREE))

printf "%-25s %10.1f GB\n" "Used" "$(echo "$USED/1024/1024" | bc -l)"

추가로 권장하는 확장 분석

위 스크립트에 다음 항목들을 함께 수집하면 원인 규명에 큰 도움이 됩니다.

  • 프로세스 RSS/PSS 집계: smem, ps_mem.py 또는 /proc/*/smaps_rollup 기반으로 실제 사용자 메모리 합계.

  • cgroup v2 메모리 상세: 모든 memory.stat을 순회하여 anon, file, kernel, slab, sock 등을 집계하고 memory.current와 비교.

  • 네트워크 메모리: /proc/net/sockstat, /proc/net/sockstat6에서 TCP/UDP 및 소켓 메모리 사용량 확인.

  • BPF/Cilium 메모리:

    • bpftool map showbytes_memlock 합계
    • bpftool prog show
    • cilium-dbg bpf map list(사용 가능 시)
  • DirectPV/파일시스템 캐시: Dirty, Writeback, Inactive(file), Active(file)를 시간에 따라 추적.

  • 커널 슬랩 상세: slabtop -o 또는 /proc/slabinfo에서 상위 캐시(dentry, inode_cache, kmalloc-*, skbuff_head_cache, xfs_inode, ext4_inode_cache 등) 확인.

  • Pinned pages: RDMA, GPU, mlock, get_user_pages() 등으로 고정된 페이지 여부.

  • Transparent Huge Pages: AnonHugePages, ShmemHugePages, FileHugePages 확인.


현재 제공해주신 수치(RSS≈200GB, Slab≈70GB, Buff/Cache≈171GB, Used≈725GB)를 보면 약 280GB 정도의 공백이 존재합니다. 일반적인 Linux 시스템이라면 이렇게 큰 차이는 흔하지 않으므로, cgroup accounting, BPF/Cilium 메모리, 파일 캐시의 상세 분류(Active/Inactive), 그리고 커널이 추적하는 기타 메모리 항목을 함께 집계하는 것이 가장 중요합니다.

원하시면 이 스크립트를 발전시켜 mem-spectrum.sh 형태로,

  • 자동 퍼센트 계산,
  • RSS/PSS,
  • cgroup(memory.current/memory.stat),
  • BPF(Cilium),
  • sockstat,
  • slab 상위 20개,
  • 최종적으로 "Used 725GB = Anon 210GB + Cache 170GB + Slab 70GB + BPF 35GB + Sock 12GB + ... + Unknown XXGB" 형태의 리포트를 한 번에 출력하도록 구성해 드리겠습니다.

0개의 댓글