smem比top/ps更精准,因其基于/proc统计USS(独占内存)和PSS(共享页均摊),避免RSS重复计算共享内存导致的误判。

排查Linux系统中占用高内存的进程,smem 是一个比 ps 或 top 更精准的工具,它基于/proc接口统计实际物理内存(RSS)和更关键的USS(Unique Set Size),能有效识别真正独占内存的进程,避免共享内存带来的误判。
为什么 smem 比 top/ps 更适合查“真实内存占用”
top 和 ps 显示的 RSS(Resident Set Size)包含大量共享内存(如 libc、glibc、动态库),多个进程共用同一段内存时会被重复计算,导致总和远超物理内存总量;而 smem 通过分析 /proc/PID/smaps 中的 MMUPageSize 和 MMUPFPageSize 等字段,精确拆分出每个进程独有的物理页(USS),并提供 PSS(Proportional Set Size,按共享页均摊后的值),结果更贴近“谁真正吃掉了内存”。
安装与基础用法
Ubuntu/Debian:sudo apt install smem
CentOS/RHEL:sudo yum install python3-smem(或启用 EPEL 后安装)
- 查看所有进程按 USS 降序排列:smem -s uss -r
- 只显示前 10 个内存大户:smem -s uss -r -n 10
- 按用户汇总内存使用(含 USS/PSS/RSS 总和):smem -u
- 生成 HTML 报告便于浏览:smem --html -c "name pid user uss pss rss" > mem_report.html
关键指标解读:USS、PSS、RSS
USS(Unique Set Size):进程独占的物理内存页,不与其他进程共享。是判断“该进程是否泄漏内存”的黄金指标。
PSS(Proportional Set Size):USS + 共享页 ÷ 共享该页的进程数。适合评估单个进程对系统整体内存压力的贡献。
RSS(Resident Set Size):传统意义上的常驻内存,含全部共享页,易高估单个进程影响。
例如:5 个 Java 进程共用 100MB 的 JVM 共享库,则每个进程 RSS 多算 100MB,但 USS 不含这部分,PSS 只加 20MB。
结合 smem 定位异常进程的实用技巧
- 优先排序 USS:smem -s uss -r | head -20,USS 突然增长的进程大概率存在内存泄漏或缓存失控
- 对比同类型进程:比如多个 nginx worker,若某个 USS 是其他 worker 的 5 倍以上,需检查其处理的请求是否有异常(如大文件上传、长连接堆积)
- 过滤特定用户或命令:smem -P java -s uss -r 查所有 Java 进程;smem -U www-data 查 www-data 用户下所有进程内存分布
- 配合 pstack 或 jstack 进一步分析高 USS 进程的线程栈或堆状态
注意 smem 的局限性
smem 依赖 /proc/PID/smaps 数据,内核需开启 CONFIG_PROC_PAGE_MONITOR(主流发行版默认开启);容器环境(如 Docker)中,若未挂载 /proc 为 rprivate 或使用了 cgroup v2 的某些配置,可能无法读取完整 smaps;另外,smem 不实时刷新,适合做快照分析而非持续监控 —— 长期监控建议搭配 prometheus + node_exporter。










