2

我试图在操作系统级别上围绕 Windows 内存管理的内部结构。

是不是在分配内存的时候,总会在幕后触发缺页?这是否意味着停止软页面错误的唯一方法是停止在进程中分配新内存?

定义

我将“内存分配”定义为任何形式的 malloc,即 new、LocalAlloc、VirtualAlloc、HeapAlloc 等。

我将“页面错误”定义为将内存从 OS 池映射到进程工作集的过程,该操作在高端 Xeon 上需要 250us 的常数。

4

2 回答 2

9

您需要非常清楚这里发生的不同事情。进程有两个独立的部分,提交内存和将内存分页到进程中。这些都与调用malloc,HeapAlloc或无关LocalAlloc

我试图在下面为您分解该过程,但总结是,如果您使用HeapAlloc或其他等效函数,那么您将触发很少的页面错误(至少在您的应用程序初始化并且堆增长到稳定的大小),所以不应该太担心它。

分配内存

当您调用时malloc,内存分配器将尝试在堆中找到一块可用且足够大的内存。在大多数情况下,它会成功并将内存返回给您。HeapAllocLocalAlloc

如果找不到足够的内存,它将通过调用VirtualAlloc(在 Linux 上为sbrkor mmap)分配更多内存。这会提交内存。它会将新记忆的一小部分返回给您。

内存承诺

当您或分配器调用VirtualAlloc它时,会将您的虚拟内存的新区域标记为可访问。这不会触发页面错误,也不会实际为这些页面分配物理内存。来自 VirtualAlloc 的 MSDN 文档:

为指定的保留内存页面分配内存费用(来自内存的整体大小和磁盘上的页面文件)。该函数还保证当调用者稍后最初访问内存时,内容将为零。除非/直到实际访问虚拟地址,否则不会分配实际的物理页面。

分页内存

当您访问第一次返回给您的内存页面时,VirtualAlloc这会触发软页面错误。操作系统将找到一个可用物理内存页面,将其清零并将其分配给您访问的虚拟页面。这对您来说是透明的,并且只需要很少的时间(一位数的微秒)。如果您停止使用它,操作系统可能会将此内存交换到磁盘,如果它确实如此,那么后续访问将触发硬页面错误。

于 2012-09-03T15:10:58.053 回答
1

嗯,是的,页面错误将使 CPU 回到内核模式,内核有机会获悉用户空间进程需要某个内存页面。然后内核可以查询其内部内存管理簿记数据,提供适当大的物理内存区域,并调整处理器的页表以便映射请求的虚拟地址。完成后,执行将返回到用户空间进程,该进程会在分配成功后继续。

这不要与意外的页面错误相混淆,用户空间进程引用的地址既没有映射到页表中,也没有被内核的内存管理器知道属于该进程。在这种情况下,内核将杀死流氓进程。

于 2012-09-03T13:40:05.593 回答