【问题标题】:Linux kernel: is a re-assigned page frame cleared?Linux内核:是否清除了重新分配的页框?
【发布时间】:2022-06-15 06:46:36
【问题描述】:

当一个进程结束时,Linux 内核可以将用户空间页面帧(物理内存中的页面)重新分配给另一个进程的用户空间页面(虚拟内存中)。

在重新分配之前是否清除了页框?否则旧内容可能对另一个进程可见,我无法想象这是允许的。一种情况是将页框分配给不断增长的堆,其中旧内容可能在分配的内存中可见。

【问题讨论】:

  • 是的,页面内容在映射到进程之前会被初始化。例如,如果 GNU 内存分配器(在 glibc 中)使用 mmap 获得更多内存,则该内存将被清零。我认为它从“写入时复制”(COW)引用开始,当进程写入页面时,该页面会被复制到普通页面。
  • 这就是为什么您的用户空间库可能不会免费将页面返回给系统,而是保留它们以供后续分配。它保存系统调用并清除页面。

标签: linux linux-kernel paging


【解决方案1】:

是的,“重新分配”的物理内存已被清除,但具体如何以及何时清除有点棘手。该页面不会立即被清除,而是在另一个进程映射它之后的第一个 write 页面错误。

假设一个匿名的“按需填零”页面:

  1. 用户程序 A 正在使用物理地址为 PA 的内存页。
  2. 用户程序 A 终止执行,内核收回内存,物理内存内容仍未改变
  3. 用户程序 B(或者甚至 A,没关系)启动并请求内存页。
  4. 内核为请求的页面创建一个虚拟映射。
  5. 用户程序 B 写入映射,导致写入页面错误。
  6. 内核分配内存,获取物理地址为PA的物理页,同第1点。
  7. 内核清除页面(清零之前的任何内容)并相应地更新虚拟映射(页表等)。

因此,实际的清除是“延迟”发生的,可能比内存被释放并被内核收回时(第 2 步)晚很多(第 7 步)。

注意:对于新创建的匿名映射的第一个 read 页面错误会发生什么情况则完全不同。内核始终保持一个完全归零的物理页面(称为“零页面”),并创建到该页面的虚拟映射。每个需要它的进程都会发生这种情况,因此零页在不同进程的多个 VMA 中被多次映射。这样做是为了提高性能(无需将任何内容归零)和节省内存(在写入发生之前无需分配新页面)。


关于写入错误,即页面实际被清除时,内核中可能的代码路径之一是:

【讨论】:

  • 非常感谢您的深入回答。只有一个问题:可能程序 B 的 read 尝试也会导致页面错误并导致页面框架的初始化?
  • @Ralf 不,这是一个稍微不同的故事。我编辑了答案以添加此信息。
猜你喜欢
  • 2010-11-22
  • 1970-01-01
  • 2012-05-27
  • 2013-08-25
  • 2021-12-30
  • 2016-06-03
  • 1970-01-01
相关资源
最近更新 更多