Linux 内存占用过高排查思路总结

1次阅读

Linux 内存占用过高排查思路总结

linux 内存占用高,不能只看 free -h 的“used”值就断定有问题——Linux 会尽可能利用空闲内存做缓存(buffers/cache),这部分在需要时可立即回收。真正要关注的是是否发生了频繁换页、OOM Killer 是否被触发、以及哪些进程或内核对象长期占用了不可回收内存。

第一步:确认是否真存在内存压力

运行以下命令快速判断:

  • free -h:重点关注 available 列(内核 3.14+ 提供),它表示当前可立即分配给新进程的内存,比 “used” 更具参考价值;若 available 长期接近 0,才说明有真实压力。
  • cat /proc/meminfo | grep -E "^(MemAvailable|SwapTotal|SwapFree|OomKillCount)":检查 MemAvailable 是否持续偏低、Swap 是否被大量使用、OomKillCount 是否非零(说明 OOM 已发生)。
  • vmstat 1 5:观察 si(swap in)和 so(swap out)是否持续大于 0,以及 bi/bo(块设备 I/O)是否异常高——这往往意味着内存不足导致频繁换页或缓存抖动。

第二步:定位高内存消耗的用户进程

优先排查用户态进程:

  • ps aux --sort=-%mem | head -10:按内存使用率倒序列出前 10 个进程,注意看 RSS(常驻内存集)和 %MEM。
  • tophtop(需安装):按 M 键按内存排序,实时观察 RSS 和 VIRT 变化;留意进程状态(如 D 状态可能因等待 I/O 卡住并持有内存)。
  • 对可疑进程进一步分析:pmap -x <pid></pid> 查看其内存段分布;cat /proc/<pid>/status | grep -E "^(VmRSS|VmSize|MMUPageSize|RssAnon|RssFile)"</pid> 区分匿名内存(/)和文件页(如 mmap 的共享库)。

第三步:检查内核内存与特殊内存占用

当用户进程 RSS 总和远低于 total used,问题往往出在内核侧:

  • slabtop:查看内核 slab 分配器占用,重点关注 cache 列中排名靠前的项(如 dentry、inode、ext4_inode_cache、kmalloc-*)。若某 cache 持续增长且不释放,可能是文件系统句柄泄漏或内核模块异常。
  • cat /proc/meminfo | grep -E "^(SReclaimable|SUnreclaim|PageTables|KernelStack|CommitLimit|Committed_AS)":SReclaimable 是可回收的 slab(如 dentry/inode 缓存),SUnreclaim 是不可回收的(如某些驱动分配的内存);PageTables 和 KernelStack 过大可能暗示进程数过多或内核栈泄漏。
  • find /sys/kernel/slab/ -name 'slabs' -exec sh -c 'echo {} ; cat {}/slabs' ; 2>/dev/NULL | sort -k2 -nr | head -10:辅助定位高 slabs 数量的 cache。

第四步:识别隐性内存大户:内存映射与大页

某些内存不体现在进程 RSS,但实际占用物理页:

  • grep -i "mmapped" /proc/*/smaps 2>/dev/null | awk '{sum += $2} END {print sum " kB"}':粗略统计所有进程 mmap 的内存总量(含共享库、mmap 文件、hugepage 映射等)。
  • cat /proc/meminfo | grep -i "huge":检查 HugePages_Total / Free,若应用未启用 hugetlb,却有大量已分配 hugepage,可能是配置残留或内核参数误设(如 vm.nr_hugepages 设置过大)。
  • ls -l /dev/shm /run /var/run:检查 tmpfs 挂载点(如 /dev/shm)是否被写入大量数据(例如 redis 持久化到 shm、容器 runtime 临时文件堆积)。

排查不是线性流程,常需交叉验证。比如发现 slab 占用高,同时 lsof +L1 显示大量被删除但仍打开的文件,就可能指向 dentry/inode 泄漏;又如 Committed_AS 接近 CommitLimit,即使 available 尚可,也预示着 fork 大量进程时可能触发 OOM。核心是理解 Linux 内存管理机制,再结合指标找矛盾点。

text=ZqhQzanResources