为什么MemAvailable比MemFree+Buffers+Cached少很多?

为什么MemAvailable比MemFree+Buffers+Cached少很多?

我正在运行一个没有交换的 Linux 工作站,并且我已经安装了earlyoom如果内存不足,守护进程会自动终止某些进程。它earlyoom通过监控内核MemAvailable值来工作,如果可用内存足够低,它会终止不太重要的进程。

长期以来,这种方法一直运行良好,但突然间,我遇到了MemAvailable与系统其他部分相比,其性能突然变得非常低的情况。例如:

$ grep -E '^(MemTotal|MemFree|MemAvailable|Buffers|Cached):' /proc/meminfo 
MemTotal:       32362500 kB
MemFree:         5983300 kB
MemAvailable:    2141000 kB
Buffers:          665208 kB
Cached:          4228632 kB

请注意 MemAvailable 远低于MemFree++ BuffersCached

我可以运行什么工具来进一步调查为什么会发生这种情况?我感觉系统性能比平时差一点,我不得不停止该服务,因为除非它稳定(即,它正确地向用户模式进程描述可用内存),earlyoom否则它的逻辑将无法工作。MemAvailable

根据https://superuser.com/a/980821/100154MemAvailable 是在不进行交换的情况下,估计有多少内存可用于启动新应用程序。由于我没有交换,这是什么意思?这是否意味着在触发 OOM Killer 之前新进程可以获得的内存量(因为这在逻辑上会遇到“交换已满”的情况)?

我曾假设MemAvailable>=MemFree永远为真。但这里不是。

附加信息:

在互联网上搜索后,我发现原因可能是文件系统不支持打开文件,因此无法从内存中释放这些文件。命令sudo lsof | wc -l输出结果显示653100,因此我绝对无法手动查看该列表。

顶部sudo slabtop

 Active / Total Objects (% used)    : 10323895 / 10898372 (94.7%)
 Active / Total Slabs (% used)      : 404046 / 404046 (100.0%)
 Active / Total Caches (% used)     : 104 / 136 (76.5%)
 Active / Total Size (% used)       : 6213407.66K / 6293208.07K (98.7%)
 Minimum / Average / Maximum Object : 0.01K / 0.58K / 23.88K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
4593690 4593656  99%    1.06K 153123       30   4899936K ext4_inode_cache
3833235 3828157  99%    0.19K 182535       21    730140K dentry
860224 551785  64%    0.06K  13441       64     53764K kmalloc-64
515688 510872  99%    0.66K  21487       24    343792K proc_inode_cache
168140 123577  73%    0.20K   8407       20     33628K vm_area_struct
136832 108023  78%    0.06K   2138       64      8552K pid
...

这对我来说看起来很正常。

创建粗略摘要lsof

$ sudo lsof | awk '{ print $2 }' | sort | uniq -c | sort -h | tail
   6516 1118
   7194 2603
   7884 18727
   8673 19951
  25193 28026
  29637 31798
  38631 15482
  41067 3684
  46800 3626
  75744 17776

指向我的 PID 17776,这是一个 VirtualBox 实例。(其他打开大量文件的进程是 Chrome、Opera 和 Thunderbird。)因此,如果我后来发现这个问题的主要原因是 VirtualBox,我不会感到太惊讶,因为这是唯一真正扰乱内核的东西。

然而,即使我关闭 virtualbox 并终止 Chrome、Opera 和 Thunderbird,问题仍然没有消失。

答案1

我可以运行什么工具来进一步调查为什么会发生这种情况?

差异可能是因为您使用了错误的计算。您链接到的答案没有突出显示这一点,但请查看链接的提交消息:

[人们]通常通过将“空闲”和“缓存”相加来实现这一点,这在十年前是可行的,但今天几乎肯定是错误的。这是错误的,因为其中Cached包括不能作为页面缓存释放的内存,例如共享内存段、tmpfs 和 ramfs。

其中不能作为页面缓存释放的部分Cached(叹气)被 Shmem算作/proc/meminfo

您也可以运行free,并查看“共享”列。

这通常是由于已安装tmpfs. 检查造成的df -h -t tmpfs

答案2

正如您在所引用的文章中所看到的,围绕 MemAvailable 的整套计算都是围绕计算有多​​少内存可供使用而不会导致任何交换而构建的。您可以在实际补丁实现了 MemAvailable 数字,即 MemAvailable = MemFree - LowWaterMark + (PageCache - min(PageCache / 2, LowWaterMark))

此公式指出了系统的 MemAvailable 较低的概率,因为您的低水位标记(系统认为需要作为工作空间的可用内存量)可能非常高。这在无交换环境中是有意义的,因为系统更担心内存耗尽。您可以查看当前的低水位标记是多少:

 $ cat /proc/sys/vm/min_free_kbytes

我怀疑就你的情况来说,这个数字相当高。

Linux 内存管理中的几乎所有启发式方法都假设您将使用一些交换空间进行操作。

答案3

对于现代 Linux 内核,该Cached值包含磁盘缓存所有共享内存。由于只能删除磁盘缓存,因此不能将其视为可用内存。我在邮件列表中询问了这个问题linux-mm,普遍的共识是,Cached由于向后兼容,计算方式不能改变,尽管当前计算对于标签“缓存”有点问题。传统的缓存值应(Cached - Shmem)与现代内核一样计算。

如今,您应该相信MemAvailable在实践中描述实际可用的内存。如果您想要更详细的细分,您可能应该从中获取数据/proc/meminfo并计算Free++ 。该计算不同于释放非活动文件缓存需要 IO。还要注意,如果内核实际上要释放所有,Inactive(file)那么整体吞吐量也可能会受到很大影响。是一种启发式方法,它试图猜测可以在当前工作负载之上使用的可用 RAM,而不会严重损害当前工作负载的吞吐量。这显然不同于不会导致系统崩溃的理论最大可用内存。KReclaimableMemAvailableKReclaimableMemAvailable

相关内容