原力注入

Linux 小技巧 - 使用 smem 了解内存使用情况

在为资源密集型应用程序优化性能时,洞察系统和进程内存使用非常重要。虽然像 top 和 htop 这样的工具通常用于监控系统性能,但它们通常不提供足够的内存使用细分详情。

什么是 smem?

smem 是一个命令行工具,它报告每个进程的内存使用情况,并提供比大多数传统工具更好的共享内存洞察,考虑到共享内存页面。与主要显示 RSS(驻留集大小)的 top 或 htop 不同,smem 还可以显示 USS(唯一集大小),这是评估终止特定进程将释放多少内存的更好指标。

理解内存指标:RSS、USS 和 PSS

Image

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 smem

CentOS 可以用如下命令安装:

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.