匿名内存是否是Linux页面缓存的一部分?

5
匿名内存”(即程序堆和栈)是否是Linux页面缓存的一部分?内核的链接文档没有说明这一点。但是,页面缓存的维基百科条目包含一个图形(请看右上角),给我留下了malloc()在页面缓存中分配动态内存的印象:
linux storage stack diagram from thomas krenn 这有意义吗?关于“mmap()”,当它用于访问文件时,使用页面缓存是有意义的。对于匿名内存,例如“malloc()”和通过“mmap()”进行的匿名映射,通常也是如此。我希望得到一些解释。谢谢。 编辑于2021年3月14日
我决定向内存子系统的内核维护者们发送邮件询问邮件列表。幸运的是,Matthew Wilcox回复并帮助了我。摘录如下:
  • 匿名内存不由页面缓存处理。
  • 匿名页面以多种不同的方式处理 - 它们可以在LRU列表(最近最少使用)中找到,也可以通过页表找到。有点临时性。
  • 维基百科的图表是错误的,并且存在其他缺陷。
  • 如果系统提供交换空间,并且匿名内存被交换 - 它会进入交换缓存,而不是页面缓存
这个讨论可以在这里或者这里阅读。

匿名内存由交换区支持,而不是文件系统。除此之外,它基本上与任何其他虚拟内存相同。 - Barmar
我投票关闭此问题,因为这不是一个编程问题。它似乎更适合 [cs.se]。 - Barmar
4
我尊重地不同意Barmar的观点。这个问题特别涉及Linux,一个全面的答案应该包括Linux内核编程材料/参考资料。在计算机科学领域,根本不存在Linux标签。此外,链接的计算机科学标签中只有数百名关注者,而仅Linux标签就有164,000名关注者。希望这个问题能保持开放状态,因为在这里得到回答的可能性更大。 - wxz
1
我知道过度规范化是一个问题。我自己被这里类似的网站和重叠的范围所困惑。无论如何 - 我会尽力得到答案 :) - Peter
2
CS已关闭了这个问题并建议其他网站,即SO。我在SO上取消了自己的关闭投票,并希望有人在这里回答。我希望广泛的网站可以接受疑问问题,并努力获取知识。 - Peter
显示剩余4条评论
1个回答

3
TLDR: 不可以,除了像IPC shmem这样具有特殊文件系统支持的匿名内存。

更新:根据内核邮件列表讨论中的新信息,更正了答案。


页面缓存最初旨在成为操作系统级内存区域,用于快速查找磁盘文件,并且其最初形式是缓冲高速缓存(用于缓存来自磁盘的块)。页面缓存的概念在Linux诞生后的1995年后才出现,但前提类似,只是一种新的抽象——页面[1]。实际上,最终两个缓存合并成了一个:页面缓存包括缓冲高速缓存,或者说,缓冲高速缓存就是页面缓存[1, 2]。

所以页面缓存中放了什么?除了传统的磁盘支持文件外,为了使页面缓存尽可能地通用,Linux 还有一些页面类型的示例,它们不遵循传统的磁盘支持页面的概念,但仍存储在页面缓存中。当然,如前所述,缓冲区缓存(与页面缓存相同)用于存储支持磁盘数据块。块不一定与页面大小相同。实际上,我了解到它们可以比页面小 [3 的第 323 页]。在这种情况下,被视为缓冲区缓存一部分的页面可能由对应于磁盘上非连续内存区域的多个块组成。我不清楚在这种情况下,缓冲区缓存中的每个页面是否必须是页面和文件之间的一对一映射,或者一个页面是否可以由来自不同文件的块组成。尽管如此,这是一个不遵循原始页面缓存的最严格定义的页面缓存使用方法。
下一个是交换缓存。正如Barmar在评论中提到的那样,匿名页面(非文件支持的页面)可以被交换到磁盘上。在到达磁盘并返回的过程中,页面被放置在交换缓存中。交换缓存重新使用与页面缓存类似的数据结构,具体来说是address_space结构,但设置了交换标志并具有一些其他差异[见4的第731页,5]。然而,由于交换缓存被视为与页面缓存分开,因此交换缓存中的匿名页面不被认为是“在页面缓存中”。

最后一个问题是关于mmap/malloc是否在页缓存中分配内存。正如[5]所讨论的那样,通常情况下,mmap使用来自空闲页面列表的内存,而不是页缓存(除非没有剩余的空闲页面)。当使用mmap映射文件进行读写时,这些页面最终会驻留在页缓存中。然而,对于匿名内存,mmap/malloc的页面通常不驻留在页缓存中。

有一个例外是具有特殊文件系统支持的匿名内存。例如,用于进程间通信的共享内存 mmap 是由基于 RAM 的 tmpfs 支持的 [6]。这个内存位于页面缓存中,但是是匿名的,因为它没有磁盘支持的文件 [4]。

来源:

  1. https://lwn.net/Articles/712467/
  2. https://www.thomas-krenn.com/en/wiki/Linux_Page_Cache_Basics
  3. https://www.doc-developpement-durable.org/file/Projets-informatiques/cours-&-manuels-informatiques/Linux/Linux%20Kernel%20Development,%203rd%20Edition.pdf
  4. https://doc.lagout.org/operating%20system%20/linux/Understanding%20Linux%20Kernel.pdf
  5. https://lore.kernel.org/linux-mm/20210315000738.GR2577561@casper.infradead.org/
  6. https://github.com/torvalds/linux/blob/master/Documentation/filesystems/tmpfs.rst

1
这似乎暗示堆栈内存不能被换出,但它肯定是可以被换出的。 - Nate Eldredge
我认为你是正确的,当我在写栈时,我心里想的是非交换页面缓存,就像在mmap/malloc的情况下一样。 - wxz
请阅读我问题的编辑。关于匿名内存(堆栈和堆)部分,您的答案是不正确的。我不想在这里回答自己的问题,因为实际上Matthew Wilcox已经回答了。 - Peter
@Peter 感谢你尝试从内核邮件列表中获取最新的答案。我对进一步探索此事很感兴趣。如果你不介意,我会加入这个电子邮件链。 - wxz
我更正了我的答案,包括新的信息。如果我漏掉了什么,请随意提出建议,以便我们在SO上有一个漂亮的、大多数是最新的答案。 - wxz
1
干得好。我们获得了知识并结识了有用的人!我不熟悉维基百科的内部情况,但我从“页面缓存”条目中删除了图表,现在正在寻找最好的方法处理其他包含该图表的条目。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接