“高速缓存”存储器实际上是免费的吗?


11

运行时cat /proc/meminfo,您将在顶部获得以下三个值:

MemTotal:        6291456 kB
MemFree:         4038976 kB
Cached:          1477948 kB

据我所知,“已缓存”值是Linux系统创建的磁盘缓存,如果任何应用程序需要更多RAM,它将立即释放,因此Linux永远不会用完内存,直到MemFree和“已缓存”都为零。

不幸的是,/ proc / meminfo没有报告“ MemAvailable”,可能是因为它在虚拟服务器中运行。(内核版本为4.4)

因此,出于所有实际目的,可用于应用程序的RAM是MemFree + Cached。

这种观点正确吗?


1
我不想对此事一掷千金,但如果不是重复的话,这个问题也很重要。我很惊讶您没有MemAvailable它,它是在3.14中添加的。
史蒂芬·基特

从这个问题接受的答案使用的/ proc / zoneinfo中,这是不是可以用我的虚拟服务器,以及
罗兰Seuhs

uname -a:Linux主机4.4.0-042stab134.8#1 SMP Fri Dec 7 7 Dec 17:16:09 MSK 2018 x86_64 x86_64 x86_64 GNU / Linux
Roland Seuhs

我怀疑这是一个OpenVZ系统,其内核确实基于2.6.32,而不是4.4。
斯蒂芬·基特

1
@sourcejedi,它与4.4内核完全在同一时间编译!
斯蒂芬·基特

Answers:


10

在许多实际案例中,这种观点可能会产生误导。

现在,内核会在MemAvailable现场提供对可用内存的估计。该值与明显不同MemFree + Cached

/ proc / meminfo:提供估计的可用内存 [内核更改说明,2014年]

许多负载平衡和工作负载放置程序会检查/ proc / meminfo来估计有多少可用内存。他们通常通过将“免费”和“缓存”相加来做到这一点,这在十年前还不错,但是今天几乎可以肯定是错误的。

这是错误的,因为“高速缓存”包含不可作为页面高速缓存释放的内存,例如共享内存段,tmpfs和ramfs,并且不包含可回收的平板内存,在大多数闲置系统中,这些内存会占用系统内存的很大一部分。很多文件。

当前,可以根据MemFree,Active(file),Inactive(file)和SReclaimable以及/的“低”水印来估计可用于新工作负载的内存量,而无需将系统推入交换状态。 proc / zoneinfo。但是,这种情况将来可能会改变,并且实际上不应期望用户空间知道内核的内部结构来估计可用内存量。在/ proc / meminfo中提供这样的估计更为方便。如果将来情况发生变化,我们只需要在一个地方进行更改。
...

Documentation / filesystems / proc.txt:
...
MemAvailable:估计有多少内存可用于启动新应用程序而无需交换。根据MemFree,SReclaimable,文件LRU列表的大小以及每个区域中的低水位线计算得出。该估计考虑到系统需要一些页面缓存才能正常运行,并且由于正在使用项目,并非所有可回收的平板都将是可回收的。这些因素的影响因系统而异。

1.可用的详细信息

如上所述,tmpfs和其他Shmem内存无法释放,只能移动到swap。 由于包含了该可交换内存,因此Cachedin /proc/meminfo可能会引起误导Shmem。如果tmpfs中文件过多,则可能会占用大量内存:-)。 Shmem还可以包含一些图形内存分配,这可能会很大。

MemAvailable故意不包括可交换内存。交换过多会导致长时间的延迟。您甚至可能选择不使用交换空间运行,或者只允许相对有限的数量运行。

我必须仔细检查MemAvailable工作原理。乍一看,该代码似乎没有提到这种区别。

/*
 * Not all the page cache can be freed, otherwise the system will
 * start swapping. Assume at least half of the page cache, or the
 * low watermark worth of cache, needs to stay.
 */
pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
pagecache -= min(pagecache / 2, wmark_low);
available += pagecache;

但是,我发现它正确地视为Shmem“已用”内存。我在tmpfs中创建了几个1GB的文件。每增加1GB,Shmem减少MemAvailable1GB。因此,“文件LRU列表”的大小不包括共享内存或任何其他可交换内存。(我注意到在计算“脏污限制”的代码中也使用相同的页数)。

MemAvailable计算还假定您要保留至少足够的文件高速缓存,以等于内核的“低水印”。或当前缓存的一半-以较小者为准。(对于可回收的平板也做出相同的假设)。可以调整内核的“低水印”,但通常约为系统RAM的2%。因此,如果您只想粗略估算,则可以忽略此部分:-)。

当您firefox在页面高速缓存中映射大约100MB的程序代码运行时,通常需要将该100MB保留在RAM中:-)。否则,充其量你将受到延误,在最坏的情况,系统将花费其所有的时间颠簸不同的应用程序之间。因此MemAvailable,为此只允许一小部分RAM。它可能不够用,或者可能过于宽泛。“这些因素的影响将因系统而异”。

对于许多PC工作负载,关于“大量文件”的观点可能并不重要。即使这样,我目前在笔记本电脑上有500MB的可回收平板内存(8GB的RAM中)。这是由于ext4_inode_cache(超过30万个对象)。发生这种情况是因为最近我不得不扫描整个文件系统,以查找正在使用我的磁盘空间的内容:-)。我使用了命令df -x / | sort -n,但是例如Gnome Disk Usage Analyzer会做同样的事情。

2. [编辑]对照组的记忆

所谓的“Linux容器”是从建立起来namespacescgroups并根据口味不同的其他功能:-)。它们可能提供足够有说服力的环境来运行几乎像完整的Linux系统一样的东西。托管服务可以像这样构建容器并将其作为“虚拟服务器”出售:-)。

主机服务器还可以使用主流Linux中没有的功能来构建“虚拟服务器”。 OpenVZ容器比主线cgroup早两年,并且可能使用“ beancounters”来限制内存。因此,如果您仅阅读文档或询问有关主线Linux内核的问题,您将无法确切了解这些内存限制是如何工作的。 cat /proc/user_beancounters显示当前用法和限制。 vzubc以更友好的格式显示。在上beancounters主要页面的文档的行名。

控制组包括对内部进程设置内存限制的功能。如果在这样的cgroup中运行应用程序,则并非所有系统内存都可供应用程序使用:-)。那么,在这种情况下,我们如何看待可用内存?

此接口在许多方面有所不同,具体取决于您使用的是cgroup-v1还是cgroup-v2

我的笔记本电脑安装使用cgroup-v1。我可以跑步cat /sys/fs/cgroup/memory/memory.stat。该文件显示了各个领域,包括total_rsstotal_cachetotal_shmem。shmem(包括tmpfs)计入内存限制。我想您可以看成total_rss是的反函数MemFree。还有一个文件memory.kmem.usage_in_bytes,表示包括板在内的内核内存。(尽管未明确记录,但我假设memory.kmem.还包括memory.kmem.tcp.及任何将来的扩展)。没有单独的计数器来查看可回收的平板内存。为cgroup中-V1文件称击中内存限制并不会触发任何平板的内存回收。(该文档也免责声明它“希望已过时”,因此您应该检查当前的源代码)。

cgroup-v2是不同的。我认为根(顶级)cgroup不支持内存记帐。cgroup-v2仍然有一个memory.stat文件。所有字段都汇总在子cgroup上,因此您无需查找total_...字段。有一个file字段,意味着做同样的事情cache。恼人的是我没有看到像rss里面这样的整体领域memory.stat; 我想您将不得不添加单个字段。可回收和不可回收平板内存有单独的统计信息;我认为v2 cgroup旨在在内存不足时回收板。

Linux cgroup不会自动虚拟化/proc/meminfo(或中的任何其他文件/proc),因此会显示整个计算机的值。这会使VPS客户感到困惑。但是,可以使用名称空间替换由特定容器软件伪造/proc/meminfo的文件。假值的有用程度取决于特定软件的功能。

systemd认为cgroup-v1无法安全地委派给例如容器。我systemd-nspawn在cgroup-v1系统上的一个容器内看了看。我可以看到它已经放置在内部的cgroup中,并且在那上面占用了内存。另一方面,所包含的资源systemd并没有建立通常的每服务cgroup进行资源核算。如果未在此cgroup内启用内存记帐,则我认为容器将无法启用它。

我假设如果您在cgroup-v2容器中,则它看起来与实际cgroup-v2系统的根目录不同,并且您将能够看到为其顶级cgroup占用的内存。或者,如果您看到的cgroup没有启用内存记帐,则希望您将被委派权限,以便可以启用systemd(或等效)内存记帐



1
它clicky nao。我使用GitHub链接是因为它们显示了包含提交的第一个版本(类似于git describe --contains)。发现它通过一个SU问题链接为TL; DR,事实证明这只是引用proc.txt中添加的部分。但是对于这个问题,提交描述只是完美的IMO :-)。
sourcejedi

MemAvailable在大多数虚拟服务器上似乎不可用...该怎么办?
罗兰·席斯

@RolandSeuhs可能学习“ beancounters”。以粗体显示编辑内容。如果您有关于beancounters的问题,请提出一个新问题,我们将不胜感激。我们总是可以从此链接到它,但是详细信息可能与使用mainline linux内核的任何读者都不相关。
sourcejedi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.