smem —— 按进程统计真实内存占用(PSS,含共享内存分摊)
这个工具是做什么的
free/top 的 RES 会把共享内存库(libc、动态库)重复计入每个进程,导致"每个进程都占 500M,加起来远超物理内存"的错觉。smem 用 PSS(Proportional Set Size) 把共享页按共享进程数分摊,给出**"每个进程真实占用的物理内存"**,是回答"内存到底被谁吃了"最准的工具。
可以回答什么问题
| 问题 | 怎么用 |
|---|---|
| 物理内存被哪些进程真正吃掉了? | smem 按 PSS 排序(默认已按 PSS 降序) |
| 共享库/共享内存算进每个进程导致虚高? | 对比 USS(独享)/PSS(分摊)/RSS(含共享)三列 |
| 按用户汇总内存占用? | smem -u |
| 内存趋势/系统级汇总? | smem -t 显示总计,smem -s rss 换排序键 |
| 只关注某进程? | smem -P <name> 按进程名过滤 |
数据来源
- 来源文件:
/proc/<pid>/smaps(每个进程的每段映射,含 Private/Rss/Shared_Clean/Shared_Dirty 明细)、/proc/<pid>/stat、/proc/meminfo。 - 采集方式:解析每个进程的
smaps,把每段映射的Shared_*部分除以共享该页的进程数,得到 PSS。 - 由此决定的特性:比 RSS 准但更慢——要逐进程扫
/proc/<pid>/smaps,进程多时开销明显;smaps_rollup(内核 4.14+)可显著加速。
一、用法
bash
yum install smem / apt install smem
smem # 进程视图,默认按 PSS 降序
smem -s rss # -s 按指定键排序(rss/pss/uss)
smem -u # 按用户汇总
smem -m # 按映射/库汇总(看哪个共享库占最多)
smem -P nginx # 只显示进程名匹配 nginx 的
smem -t # -t 末尾加总计行
smem -R 1 -S 5 # 刷新 1 秒共 5 次(持续观察)二、输出样例
bash
PID User Command Swap USS PSS RSS
1234 root nginx: worker 0 2816 4412 12800
1235 root nginx: worker 0 2816 4412 12800
1236 root nginx: worker 0 2816 4412 12800三、三列核心概念
| 列 | 含义 | 用途 |
|---|---|---|
USS | Unique Set Size:进程独享的物理内存 | 该进程自己的数据 |
PSS | Proportional Set Size:独享 + 共享页按进程数分摊 | 真实占用,多个进程相加 ≈ 物理内存总量 |
RSS | Resident Set Size:独享 + 共享页全额重复计入 | 传统 top 的 RES,会虚高 |
一句话总结:RSS 把共享库重复算导致虚高,PSS 按分摊算才是每个进程的真实物理占用——问"内存被谁吃了"用
smem,别用top的RES。