首页 > 解决方案 > 第一次将页面加载到物理内存中会导致严重的页面错误吗?

问题描述

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

例如

ptr = malloc( SIZE )

我知道这个缓冲区将保留在进程的虚拟进程空间中,我的问题是:我们第一次写入这个缓冲区时会出现严重的页面错误,如果是,为什么?

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

标签: cmallocposixvirtual-memory

解决方案


我们第一次写入这个缓冲区时会出现严重的页面错误,如果是,为什么?

第一次写入时,您可能会或可能不会遇到一个正常的页面错误。

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

  • 创建虚拟页面的malloc()原因,其中这些虚拟页面是相同的物理页面,其中充满了零,在许多虚拟地址上多次映射为“只读”(这有点像使用镜像使其看起来像一个香蕉是满屋子的香蕉)。

  • 当您第一次写入其中一个页面时,您会遇到一个页面错误,并且操作系统会分配一个新的物理页面,用零填充它,并将其映射到虚拟地址空间中的适当地址作为“读/写”(替换旧的“只读”页面充满零)。

  • 这可能发生在每个单独的虚拟页面上(例如,写入一个虚拟页面不会导致任何其他虚拟页面被分配或“读/写”)。但是,操作系统可能(如果有大量备用 RAM,和/或如果操作系统检测到易于预测的“顺序写入”模式),在您写入物理页面之前预分配物理页面(以避免将来出现页面错误);并且操作系统可能决定使用不同/更大的页面大小(例如,它可能会分配一个 2 MiB 的“大页面”而不是分配一个 4 KiB 的页面)。

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

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


推荐阅读