Contents

Linux中的过程内存管理

1. 概述

在本教程中,我们将探讨 Linux 中进程使用的四种内存测量方法;VSZ、RSS、USS 和 PSS。 每个都有自己的特点和用法,我们将在详细介绍时看到。

2. VSZ内存

VSZ 是虚拟内存大小的缩写。它是一个进程可以假设访问的内存总量。

它说明了二进制文件本身、任何链接库以及任何堆栈或堆分配的大小。

当一个进程启动时,VSZ 内存变成了 RSS 内存,我们现在就来看看。

3.RSS记忆

与 VSZ 不同,RSS 也是 Resident Set Size 的缩写,它是一种度量,用于显示在进程执行期间分配给进程的 RAM 量

但是,它实际上并不是对进程 RAM 使用情况的准确测量,因为它没有考虑已加载到内存中的库。

如果两个进程使用一个或多个库,那么 RSS 将报告每个进程的库大小,即使在一个进程接着另一个进程启动的情况下已经预先加载了库。这就是为什么 RSS 可能具有误导性并且不应该完全被信任的原因。

因为 RSS 显示整个内存输出,即使是已经预加载的信息,如果我们将进程列表中的所有内容加起来,我们将获得比分配的总内存更多的内存。

4. 使用RSSVSZ

4.1. 使用ps

检查 Linux 进程的 RSS 和 VSZ 的方法之一是调用ps

$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.1  0.0 169316 13184 ?        Ss   18:14   0:04 /sbin/init splash
root           2  0.0  0.0      0     0 ?        S    18:14   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   18:14   0:00 [rcu_gp]
// ...
root          28  0.0  0.0      0     0 ?        S    18:14   0:00 [idle_inject/3]

上面的输出只是终端中列出的所有进程的一小部分。

但正如我们所见,我们有两个名为 RSS 和 VSZ 的列,它们显示分配给每个进程的总内存和进程分配给自己的最大值。

如果我们只想查看某些进程(例如所有 Google Chrome 进程),我们可以使用:

ps eo user,pid,vsz,rss $(pgrep -f 'chrome')
USER                    PID     VSZ    RSS
blogdemo-reader        5236 1358620 333984
blogdemo-reader        5246  268300  63804
blogdemo-reader        5247  268300  63084
// ...
blogdemo-reader       36354 4587872  52700

4.2. 使用top

另一个检查进程的有用命令是top 。当我们使用它时,它会显示我们系统中运行的所有进程。 与上面的命令不同,它每次都会检查正在运行的进程列表中的变化,因此我们可以实时看到 RSS 和 VSZ 的变化。

例如,如果我们查看 PID 为 12408 的进程(在本例中为 google chrome 实例),我们可以看到例如 %CPU 的差异,它显示了该特定进程正在使用多少 CPU。正如我们在终端中看到的那样,有多个 chrome 进程在运行,这是有道理的,因为确实有多个进程在运行——实际的 chrome 应用程序、打开的选项卡、可能通过浏览器下载器进行的一些下载等——它们是在 CPU 认为合适的情况下分配更多或更少的资源:

top - 22:55:50 up  4:41,  1 user,  load average: 0,82, 2,25, 2,72
Tasks: 350 total,   1 running, 349 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0,5 us,  0,2 sy,  0,0 ni, 99,3 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
MiB Mem :  32035,2 total,  23820,8 free,   3484,8 used,   4729,7 buff/cache
MiB Swap:      0,0 total,      0,0 free,      0,0 used.  27832,6 avail Mem 
    PID USER                 PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  // ...
  12408 blogdemo-reader      20   0 9146156 312452 119532 S   1,7   1,0   9:56.70 chrome
  // ...
  12077 blogdemo-reader      20   0 4784576 182196  92716 S   0,3   0,6   1:00.59 chrome

30 秒后:

top - 22:56:20 up  4:41,  1 user,  load average: 0,63, 2,07, 2,65
Tasks: 351 total,   1 running, 350 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1,8 us,  0,5 sy,  0,0 ni, 97,7 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
MiB Mem :  32035,2 total,  23806,6 free,   3492,9 used,   4735,7 buff/cache
MiB Swap:      0,0 total,      0,0 free,      0,0 used.  27819,3 avail Mem 
    PID USER                 PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  // ...
  12408 blogdemo-reader      20   0 9185940 306080 123896 S  14,0   0,9  10:00.01 chrome
  // ...
   4340 blogdemo-reader      20   0 1171680 328412 156400 S   1,3   1,0   6:15.76 chrome
  // ...
   4579 blogdemo-reader      20   0 4723180 172064  73352 S   0,7   0,5   0:23.38 chrome
  // ...
   4414 blogdemo-reader      20   0  377528 105756  66972 S   0,3   0,3   1:33.44 chrome
   4457 blogdemo-reader      20   0  431860 120172  86228 S   0,3   0,4  20:52.63 chrome
  12691 blogdemo-reader      20   0 4737484 173728  99572 S   0,3   0,5   0:15.66 chrome
  // ...

同样,这只是输出的一小部分,但我们可以看到变化的波动性以及 CPU 排序的进程,这些进程被优先化和非优先化。

正如我们之前提到的,这些类型并不完全准确,但我们可以得到一个可靠的估计。

5. PSS内存

PSS 或 Proportional Set Size 是一种更有用的内存管理指标。它的工作方式与 RSS 完全相同,但增加了对共享库进行分区的区别。

例如,如果我们有五个进程使用相同的库,大小为 50 页,对于每个进程,PSS 报告的大小将只有 10 页用于该特定共享库。所有共享进程的所有共享库都会发生同样的事情。

PSS 的一个优点是将所有进程加在一起,我们可以很好地估计系统中的整个内存使用情况。

6. USS 内存

**唯一集大小或 USS 表示进程的私有内存。**换句话说,它显示了只分配给这个进程的库和页面

这种类型的内存也非常有用,因为它代表了启动另一个进程的实际成本。反之亦然,当一个流程结束时,它代表返回给系统的实际金额。

7. 使用 PSS 和 USS

7.1. 使用ps

要检查 Linux 进程上的 PSS 内存,我们必须访问要检查的进程的*/proc/{$PID}/smaps*。为此,我们需要我们要检查的进程的 PID。

例如,如果我们要检查rabbitmq-server进程:

$ ps -aux | grep 'rabbitmq-server'
rabbitmq    1055  0.0  0.0   2608   604 ?        Ss   iun04   0:00 /bin/sh /usr/sbin/rabbitmq-server
$ sudo cat /proc/1055/smaps | grep -w 'Pss:'
Pss:                  20 kB
Pss:                  76 kB
Pss:                  24 kB
// ...
Pss:                   0 kB

在这里,我们将看到多个 PSS 输出,如果我们将它们相加,我们将获得该过程的总 PSS 打印。或者,我们可以这样做,而不是添加大量数字:

$ sudo cat /proc/1055/smaps | grep -i 'Pss:' |  awk '{Total+=$2} END {print Total}'
165

在这里,我们以 KB 为单位报告了rabbitmq-server进程的总 PSS 内存大小。如果我们有一个使用大量 PSS 内存的进程,我们可以格式化输出以以更大的度量单位报告它:

$ sudo cat /proc/1055/smaps | grep -i 'Pss:' | awk '{Total+=$2} END {print Total/1000" MB"}'
0,165 MB

我们只需要记住除以 1000,而不是 1024,因为这是 Kilo 和 Mega 之间的差异。

7.2. 使用smem

我们用来检查 USS 的一个非常有趣的工具是smem ,我们用它来输出 USS 和其他类型:

$ sudo apt-get install smem
$ smem
  PID User                Command                         Swap      USS      PSS      RSS 
 4346 blogdemo-reader     cat                                0      116      149     1936 
 4347 blogdemo-reader     cat                                0      120      151     1884 
 2663 blogdemo-reader     /usr/libexec/gnome-session-        0      488      522     5240 
 2578 blogdemo-reader     /usr/libexec/xdg-permission        0      748      794     6320 
 2558 blogdemo-reader     /usr/bin/dbus-daemon --conf        0      668      812     4672 
 2820 blogdemo-reader     /usr/libexec/gsd-screensave        0      788      832     6404 
 2531 blogdemo-reader     /usr/libexec/ibus-memconf          0      776      859     7148 
 2803 blogdemo-reader     /usr/libexec/gsd-a11y-setti        0      832      885     6728 
 2551 blogdemo-reader     /usr/libexec/at-spi-bus-lau        0      824      893     7284 
 3192 blogdemo-reader     /usr/libexec/gvfsd-metadata        0      860      902     6376 
 2498 blogdemo-reader     /usr/libexec/gvfs-mtp-volum        0      860      906     6544 
 2431 blogdemo-reader     /usr/libexec/gvfs-goa-volum        0      904      990     6644

为了检查某个进程,我们再次使用grep 命令:

$ smem | grep -w 'chrome'
60608 ioan     grep --color=auto -w chrome        0      364      396     2588 
 4381 ioan     /opt/google/chrome/nacl_hel        0      604     1121     4132 
 4376 ioan     /opt/google/chrome/nacl_hel        0      668     1183     4204 
 4379 ioan     /opt/google/chrome/chrome -        0      204     1232    15752 
// ...
 4340 ioan     /opt/google/chrome/chrome          0   276260   290467   387636