第一次将页面加载到物理内存中会导致严重页面错误吗?

Does loading a page into physical memory for the first time cause a major page fault?

假设我们有一个刚刚创建的进程 A,它分配 SIZE 字节。

例如

ptr = malloc( SIZE )

我知道这个缓冲区将保留在进程的虚拟进程 space 中,我的问题是:我们第一次写入这个缓冲区时会遇到主要页面错误吗?如果是,为什么?

更新:这是在 ArchLinux 上使用 gcc 完成的。

will we get major page faults the FIRST time we write into this buffer, and if so why ?

您可能会或可能不会在第一次写入时出现正常页面错误。

取决于哪个OS(以及malloc()的哪个实现);但我希望(对于大多数操作系统和 malloc() 的大多数实现):

  • malloc() 导致创建虚拟页面,其中这些虚拟页面是相同的充满零的物理页面,在许多虚拟地址处多次映射为“只读”(这是一个有点像用镜子让它看起来像一个香蕉是一个装满香蕉的房间。

  • 当你第一次写入其中一个页面时,你会遇到一个页面错误,并且 OS 分配一个新的物理页面,用零填充它,并映射它在虚拟地址 space 中的适当地址作为“read/write”(替换旧的全为零的“只读”页面)。

  • 这可能发生在每个单独的虚拟页面上(例如,写入一个虚拟页面不会导致任何其他虚拟页面被分配或“read/write”)。但是,OS 可能(如果有大量备用 RAM,and/or 如果 OS 检测到容易预测的“顺序写入”模式),pre-allocate 物理页面,然后再写入给他们(以避免将来出现页面错误); OS 可能会决定使用 different/larger 页面大小(例如,它可能会分配 2 MiB 的“大页面”,而不是分配 4 KiB 的页面)。

  • 对于 malloc() 的某些实现(以及 SIZE 的某些值),一些虚拟内存可能已经在 malloc() 期间分配和映射(例如因为 malloc() 在分配块的开头写了一个 header 并导致页面错误本身)。

  • 你以后可能会遇到更多的页面错误(例如,如果你在分配页面的第一次写入时有一个页面错误;那么分配页面中的数据可能会被发送到交换 space稍后释放物理页面,然后后续读取或写入将导致更多页面错误从交换中获取数据 space).