Linux 小技巧 - 使用 smem 了解内存使用情况
在为资源密集型应用程序优化性能时,洞察系统和进程内存使用非常重要。虽然像 top 和 htop 这样的工具通常用于监控系统性能,但它们通常不提供足够的内存使用细分详情。
什么是 smem?
smem 是一个命令行工具,它报告每个进程的内存使用情况,并提供比大多数传统工具更好的共享内存洞察,考虑到共享内存页面。与主要显示 RSS(驻留集大小)的 top 或 htop 不同,smem 还可以显示 USS(唯一集大小),这是评估终止特定进程将释放多少内存的更好指标。
理解内存指标:RSS、USS 和 PSS
Resident Set Size (RSS)
**RSS(常驻集大小)**表示一个进程在 RAM 中所占用的内存部分。它包括与其他进程共享的内存(例如,共享库)。top 或 htop 等工具会显示 RSS,用于提供进程所使用内存的一个总体概念,但它 不区分共享内存和独占内存。
• RSS 是物理内存中的一部分,即已经被映射到物理内存中,正在使用的内存量。
• 它 不包含被交换(
swap)到磁盘中的内存。•
RSS也可能随着内存页被换出、共享库被加载而波动。虽然RSS直观,但它 不能准确反映进程的独占内存使用量,因此在进行内存优化时,它通常不是唯一参考指标。
Unique Set Size (USS)
USS(独占集大小)表示一个进程 独占 使用的内存量,不包括共享内存。USS 重要的原因在于,它表示 如果该进程被终止,实际能够释放的内存。因此,USS 能更准确地反映进程 真正的内存占用。
•
USS仅计算物理内存中的独占内存,不包括共享库或共享内存段。• 当进行内存分析或优化时,USS 是更可靠的指标,尤其在需要判断某个进程的 最小可释放内存 时。
• USS 通常不会直接显示在
top或htop中,需要通过特定工具获取,例如smem、pmap或procrank。
Proportional Set Size (PSS)
**PSS(比例集大小)**表示 独占内存(USS)加上共享内存的按比例分配。具体而言,每个共享内存页面会按共享进程的数量均分到每个进程的 PSS 中。
计算公式:PSS = USS + (共享内存的总大小 / 共享该内存的进程数量)
•
PSS比RSS更准确地反映了一个进程的“公平”内存占用情况,特别是在多个进程共享内存的情况下。•
PSS是 Linux 内核用于计算 OOM(Out-Of-Memory)时的重要参考指标,当系统内存不足时,PSS较大的进程更容易被选中终止。•
PSS是一种折中,既考虑了独占内存,也考虑了共享内存,因此在多进程环境中非常有用。
对比
| 指标 | 含义 | 包含内容 | 适用场景 |
RSS | 常驻集大小 | 物理内存中所有占用内存(包含共享内存) | 快速查看内存占用概况,但不够精确 |
USS | 独占集大小 | 独占的物理内存 | 判断进程结束后实际释放的内存 |
PSS | 比例集大小 | 独占内存 + 按比例分配的共享内存 | 衡量单进程的公平内存使用情况,适用于多进程环境 |
安装 smem
在 Debian、Ubuntu 和 Mint 上安装 smem,我们可以使用以下命令:
sudo apt install smemCentOS 可以用如下命令安装:
sudo yum install smem安装完成后,您就可以开始分析内存使用情况了。
smem 的基本使用
使用 smem 的最简单方式是不带任何选项运行它。这提供了所有进程的内存使用概览,显示 PID(进程 ID)、用户、命令、RSS、PSS(比例集大小)和 USS 等重要指标。
输出示例:
smem
PID User Command Swap USS PSS RSS
1351 root /sbin/agetty -o -p -- \u -- 0 308 388 2288
1313 root /usr/sbin/cron -f -P 0 296 455 3044
1321 root /usr/sbin/irqbalance --fore 0 604 829 4208
...输出参数说明:
| 参数 | 说明 |
| -a, --autosize | 自动调整列宽以适应终端大小,避免输出内容被截断。 |
| -c COLUMNS, --columns=COLUMNS | 指定要显示的列。列名称之间用空格分隔,例如 pid user rss uss。 |
| -H, --no-header | 禁用表头行,适用于脚本处理输出数据。 |
| -k, --abbreviate | 显示内存大小时使用单位后缀(如 KB、MB、GB)。 |
| -n, --numeric | 显示用户 ID (UID) 而不是用户名。 |
| -p, --percent | 以百分比显示内存使用量(RSS、USS、PSS 占总内存的比例)。 |
| -r, --reverse | 反向排序输出。 |
| -s SORT, --sort=SORT | 按指定字段排序输出,例如 rss、uss 或 pss。 |
| -t, --totals | 在输出的最后一行显示内存使用总计。 |
查看所有进程的 USS(排序)
我们可以通过 USS 对输出进行排序,以查看哪些进程使用最多的独占内存:
smem -s uss
PID User Command Swap USS PSS RSS
1313 root /usr/sbin/cron -f -P 0 296 455 3044
1351 root /sbin/agetty -o -p -- \u -- 0 308 388 2288
1321 root /usr/sbin/irqbalance --fore 0 604 829 4208
...以百分比查看内存使用情况
有时,以总系统内存的百分比查看内存使用情况很有帮助。为此,请使用 -p 标志:
smem -p
PID User Command Swap USS PSS RSS
1351 root /sbin/agetty -o -p -- \u -- 0.00% 0.00% 0.00% 0.00%
1313 root /usr/sbin/cron -f -P 0.00% 0.00% 0.00% 0.00%
1321 root /usr/sbin/irqbalance --fore 0.00% 0.00% 0.00% 0.00%
...这将包括 USS、PSS 和 RSS 的百分比列,使我们更容易理解个别进程消耗了多少系统内存。
显示系统内存
我们可以通过增加 -w 参数查看系统内存使用情况:
smem -w -k -t
Area Used Cache Noncache
firmware/hardware 0 0 0
kernel image 0 0 0
kernel dynamic memory 2.5G 1.6G 953.7M
userspace memory 332.0M 178.2M 153.8M
free memory 248.9G 248.9G 0
----------------------------------------------------------
251.8G 250.7G 1.1G查看特定进程的 USS
使用 -P 来查看特定进程的内存使用信息,注意 smem 无法直接通过选项指定单个 PID 来过滤输出,但是可以使用正则表达式过滤进程名称或命令行参数:
smem -P "^/sbin/init"
PID User Command Swap USS PSS RSS
1 root /sbin/init 0 1780 4862 13532高级选项
smem 带有多个高级选项,允许进一步自定义输出:
• 显示总计: 您可以使用
-t标志显示所有进程的总内存使用情况。
输出示例:
smem -t -k
PID User Command Swap USS PSS RSS
1351 root /sbin/agetty -o -p -- \u -- 0 308.0K 388.0K 2.2M
1313 root /usr/sbin/cron -f -P 0 296.0K 455.0K 3.0M
1321 root /usr/sbin/irqbalance --fore 0 604.0K 829.0K 4.1M
...
1788 root /usr/bin/dockerd -H fd:// - 0 78.1M 78.3M 81.6M
-------------------------------------------------------------------------------
29 6 0 294.6M 333.9M 486.3M• 按用户过滤: 要按特定用户过滤内存使用情况,请使用
-U选项后跟用户名:
smem -U syslog
PID User Command Swap USS PSS RSS
1325 syslog /usr/sbin/rsyslogd -n -iNON 0 3132 3422 6916• 图表: 对于内存使用的可视化表示,
smem还支持饼图和条形图。例如:
smem --pie uss
USS | 5.5% #############
| ############# python3
| 4.2% ########### nginx
| 3.1% ######## apache2
| 87.2% ############################ 其他进程smem --bar uss
USS | python3 ##################
| nginx ###############
| apache2 ###########
| 其他 ############################
详细可以参考:https://linux.die.net/man/8/smem.