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

Mik*_*nen 7 linux debugging kernel memory-usage

我正在运行一个没有交换的 Linux 工作站,并且我已经安装了earlyoom守护进程,以便在 RAM 不足时自动终止一些进程。它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
Run Code Online (Sandbox Code Playgroud)

请注意 MemAvailable 远低于MemFree+ Buffers+ Cached

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

根据https://superuser.com/a/980821/100154 MemAvailable 是对可用于启动新应用程序(无需交换)的内存量的估计。由于我没有交换,这是什么意思?这是否意味着在触发 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
...
Run Code Online (Sandbox Code Playgroud)

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

创建一个粗略的摘要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
Run Code Online (Sandbox Code Playgroud)

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

然而,即使我关闭 virtualbox 并终止 Chrome、Opera 和 Thunderbird,问题也不会消失。

Kur*_*ner 2

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

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

 $ cat /proc/sys/vm/min_free_kbytes
Run Code Online (Sandbox Code Playgroud)

我怀疑在你的情况下这个比例相当高。

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