是什么导致页面错误?

时间:2011-04-16 03:59:13

标签: windows x86 paging x86-64

According to Wikipedia

  

当程序访问映射到虚拟地址空间但未加载到物理内存中的页面时,页面错误是硬件引发的软件陷阱。 (强调我的)

好的,这是有道理的。

但如果是这样的话,为什么每当Process Hacker中的流程信息刷新时,我看到大约15页的错误?

Screenshot

或者换句话说,为什么任何内存被分页? (我不知道它是用户还是内核内存。)我有没有页面文件,并且4 GB中的RAM使用量大约是1.2 GB,这是在干净重启之后。没有任何资源;为什么会有任何问题被解决?

7 个答案:

答案 0 :(得分:37)

(我是Process Hacker的作者。)

首先:

  

页面错误是软件的陷阱   一个程序由硬件引发   访问映射到的页面   虚拟地址空间,但未加载   在物理记忆中。

这不完全正确,正如后面同一篇文章(次要网页错误)中所述。存在软页面错误,所有内核需要做的是将页面添加到进程的工作集。这是Windows Internals书中的一个表(我排除了导致访问冲突的书):

  • 错误原因 - 结果
  • 访问未驻留在内存中但位于页面文件或映射文件中的磁盘上的页面 - 分配物理页面,并从磁盘读取所需页面并进入相关工作集
  • 访问待机列表或修改列表中的页面 - 将页面转换为相关的流程,会话或系统工作集
  • 访问需求零页面 - 将零填充页面添加到相关工作集
  • 写入写入时复制页面 - 制作页面的进程私有(或会话私有)副本,并替换原始进程或系统工作集

如上所述,页面错误可能由于各种原因而发生。其中只有一个与从磁盘读取有关。如果您尝试从堆中分配一个块并且堆管理器分配新页面,然后访问这些页面,您将获得一个零需求页面错误。如果您尝试通过写入kernel32的页面来挂接kernel32中的函数,那么您将获得写入时复制错误,因为这些页面是以静默方式复制的,因此您的更改不会影响其他进程。

现在更具体地回答您的问题:Process Hacker在更新其服务信息时似乎只有页面错误 - 也就是说,当它调用EnumServicesStatusEx时,它会向SCM(services.exe)发送RPC。我的猜测是,在这个过程中,正在分配大量内存,导致需求为零的页面错误(服务信息需要几页存储,IIRC)。

答案 1 :(得分:5)

缓慢但稳定的页面错误源是操作系统探测不常访问的页面。在这种情况下,操作系统会标记一些不存在的页面,但会将它们保留在内存中。如果应用程序访问该页面,则会发生#PF陷阱,操作系统只会再次标记该页面,而不会再进行任何操作。如果“长时间”过去并且页面从不跳过故障,则操作系统知道如果需要,页面是交换的良好候选者。即使在没有资源压力的情况下,这种机制也可以主动运行。

答案 2 :(得分:4)

“映射到虚拟地址空间但未加载到物理内存中的页面”并不意味着它以前在物理内存中。假设您映射文件?它仍然在磁盘上,而不是在内存中。

假设您映射日志文件并继续追加它。每次超过提交的内存结束时,都会发生页面错误,操作系统会为您提供一个新的空页面并调整文件长度。


它也可能是程序捕获和处理的访问冲突。


也可能是程序使用的内存段多于TLB中的内存段(TLB是页表的缓存)。当页面是连续的时,它们都可以由单个页面表条目处理。但是,如果内存在物理地址空间中碎片化,则需要许多页表条目,并且它们可能不适合TLB。发生TLB未命中时,将调用OS页面错误处理程序并在进程的页表中查找映射。

在某些方面,这是Dean's answer的变体:页面已经在物理RAM中,并且操作系统确实需要将这些映射加载到TLB中,但不是因为IPC。

Brian指出x86(以及所有Win32系统)在没有页面错误的情况下处理这个问题。


页面错误的另一个原因是触发用于堆栈增长和写入时复制的保护页面,但通常这些页面不会在没有绑定的情况下发生。我不是100%确定这些是否会显示为访问冲突,因为它们会在进入MMU陷阱时被标记为访问冲突,但可能由操作系统页面错误处理程序处理而不会转换为用户模式(SEH)访问冲突。

答案 3 :(得分:2)

每次读取mmap'd部分时,都会生成页面错误,包括加载DLL时的错误。因此,加载DLL实际上并不会将所有DLL读入内存,只会导致代码执行时出现故障。

答案 4 :(得分:1)

在进程间共享内存时,您会看到软页面错误。基本上,如果在两个进程之间共享内存映射文件,当第二个进程加载内存映射文件时,会生成软页面错误 - 内存已经在物理RAM中,但操作系统需要修复内存管理器的表,以便您的进程中的虚拟内存地址指向正确的物理页面。

特别是像Process Hacker这样的东西,可能会在每个正在运行的进程中注入代码(为了收集信息),它可能会大量使用共享内存来进行IPC。

答案 5 :(得分:0)

操作系统使用分页对项目进行分组,这些项目应放在物理内存中,并在物理内存和共享内存之间移动。大多数情况下,放在一个页面中的数据项彼此相关。 当页面中的数据项长时间不使用时,操作系统将其移动到虚拟内存以释放物理内存中的一些空间。然后当需要页面时,操作系统将其从虚拟内存(硬盘)移动到物理内存。这是Page Fault!

并且请记住,不同的操作系统在分页算法中是不同的。

Basics of Page Faults

答案 6 :(得分:0)

资源分配是保持主存储可供使用和尽可能避免需要进入中学之间的微妙平衡。如果一个进程试图分配内存,那么这通常不是一个例外,有时候也是一个致命的例外。

基本上,你不能把所有内容都保存在没有可用资源的RAM中,因为当程序启动或要求更多时它会崩溃。