windows 什么导致页面错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5684365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What causes page faults?
提问by user541686
A page fault is a trap to the software raised by the hardware when a program accesses a page that is mapped in the virtual address space, but not loaded in physical memory. (emphasis mine)
当程序访问映射到虚拟地址空间但未加载到物理内存中的页面时,页面错误是由硬件引发的软件陷阱。(强调我的)
Okay, that makes sense.
好吧,这是有道理的。
But if that's the case, why is it that whenever the process information in Process Hacker is refreshed, I see about 15 page faults?
但是如果是这样,为什么每次刷新Process Hacker中的进程信息时,我都会看到大约15个页面错误?
Or in other words, why is any memory getting paged out? (I have no idea if it's user or kernel memory.) I have nopage file, and the RAM usage is about 1.2 GB out of 4 GB, which is after a clean reboot. There's no shortage of any resource; why would anything get paged out?
或者换句话说,为什么内存会被调出?(我不知道它是用户内存还是内核内存。)我没有页面文件,RAM 使用量约为 4 GB 中的 1.2 GB,这是在干净重启之后。不缺任何资源;为什么会有任何东西被调出?
回答by wj32
(I'm the author of Process Hacker.)
(我是 Process Hacker 的作者。)
Firstly:
首先:
A page fault is a trap to the software raised by the hardware when a program accesses a page that is mapped in the virtual address space, but not loaded in physical memory.
当程序访问映射到虚拟地址空间但未加载到物理内存中的页面时,页面错误是由硬件引发的软件陷阱。
That's not entirely correct, as explained later in the same article (Minor page fault). There are soft page faults, where all the kernel needs to do is add a page to the working set of the process. Here's a table from the Windows Internals book (I've excluded the ones that result in an access violation):
这并不完全正确,正如稍后在同一篇文章(次要页面错误)中所解释的那样。有软页面错误,所有内核需要做的就是向进程的工作集添加一个页面。这是 Windows Internals 书中的表格(我排除了导致访问冲突的表格):
- Reason for Fault - Result
- Accessing a page that isn't resident in memory but is on disk in a page file or a mapped file - Allocate a physical page, and read the desired page from disk and into the relevant working set
- Accessing a page that is on the standby or modified list - Transition the page to the relevant process, session, or system working set
- Accessing a demand-zero page - Add a zero-filled page to the relevant working set
- Writing to a copy-on-write page - Make process-private (or session-private) copy of page, and replace original in process or system working set
- 故障原因 -结果
- 访问不在内存中但在页面文件或映射文件中的磁盘上的页面 -分配物理页面,并从磁盘读取所需的页面并进入相关工作集
- 访问备用或修改列表中的页面-将页面转换到相关进程、会话或系统工作集
- 访问零需求页面 -将零填充页面添加到相关工作集
- 写入写时复制页面 -制作页面的进程私有(或会话私有)副本,并替换进程或系统工作集中的原始副本
Page faults can occur for a variety of reasons, as you can see above. Only one of them has to do with reading from the disk. If you try to allocate a block from the heap and the heap manager allocates new pages, then accesses those pages, you'll get a demand-zero page fault. If you try to hook a function in kernel32 by writing to kernel32's pages, you'll get a copy-on-write fault because those pages are silently being copied so your changes don't affect other processes.
页面错误的发生有多种原因,如上所示。其中只有一个与从磁盘读取有关。如果您尝试从堆中分配一个块并且堆管理器分配新页面,然后访问这些页面,您将遇到需求零页面错误。如果您尝试通过写入 kernel32 的页面来挂钩 kernel32 中的函数,您将收到写时复制错误,因为这些页面正在被静默复制,因此您的更改不会影响其他进程。
Now to answer your question more specifically: Process Hacker only seems to have page faults when updating its service information - that is, when it calls EnumServicesStatusEx, which RPCs to the SCM (services.exe). My guess is that in the process, a lot of memory is being allocated, leading to demand-zero page faults (the service information requires several pages to store, IIRC).
现在更具体地回答您的问题:Process Hacker 在更新其服务信息时似乎只有页面错误 - 也就是说,当它调用EnumServicesStatusEx 时,它会向 SCM (services.exe) 发送 RPC。我的猜测是在这个过程中,大量内存被分配,导致需求零页面错误(服务信息需要几个页面来存储,IIRC)。
回答by srking
A slow but steady source of page faults is the OS probing for infrequently accessed pages. In this case, the operating system marks some pages not present, but leaves them in memory as-is. If an application accesses the page, then the #PF trap occurs and the OS simply marks the page present again without further ado. If a "long time" passes and a page never trips a fault, then the OS knows the page is a good candidate for swapping should the need arise. This mechanism can run proactively even in times of no resource pressure.
一个缓慢但稳定的页面错误源是操作系统探测不常访问的页面。在这种情况下,操作系统将某些页面标记为不存在,但将它们按原样保留在内存中。如果应用程序访问该页面,则会发生 #PF 陷阱,操作系统只需将页面标记为再次出现即可。如果“很长时间”过去了并且页面从未发生故障,则操作系统知道该页面是在需要时进行交换的良好候选者。即使在没有资源压力的情况下,这种机制也可以主动运行。
回答by Ben Voigt
"page that is mapped in the virtual address space, but not loaded in physical memory" does not imply that it previously was in physical memory. Suppose you map a file? It's still on disk, not in memory yet.
“在虚拟地址空间中映射但未加载到物理内存中的页面”并不意味着它以前在物理内存中。假设你映射一个文件?它仍在磁盘上,不在内存中。
Suppose you map a log file and keep appending to it. Every time you exceed the end of committed memory, a page fault occurs, the OS will provide you with a new empty page and adjust the file length.
假设您映射了一个日志文件并继续附加到它。每次超过提交内存的末尾,就会发生页面错误,操作系统将为您提供一个新的空页面并调整文件长度。
It could also be access violations which are caught and handled by the program.
它也可能是由程序捕获和处理的访问冲突。
It could also be that the program uses more memory segments than fit in the TLB (which is a cache for the page tables). When pages are contiguous, they can all be handled by a single page table entry. But if memory is fragmented in physical address space, many page table entries are needed, and they may not fit in the TLB. When a TLB miss occurs, the OS page fault handler is invoked and looks up the mapping in the process's page table.
也可能是程序使用了比 TLB(它是页表的缓存)更多的内存段。当页是连续的时,它们都可以由单个页表条目处理。但是如果内存在物理地址空间中是碎片化的,则需要许多页表条目,并且它们可能无法放入 TLB。当发生 TLB 未命中时,操作系统页面错误处理程序被调用并在进程的页表中查找映射。
In some ways, this is a variation on Dean's answer: the pages are already in physical RAM, and the OS does need to load those mappings into the TLB, but not because of IPC.
在某些方面,这是Dean 回答的变体:页面已经在物理 RAM 中,操作系统确实需要将这些映射加载到 TLB 中,但不是因为 IPC。
Brian pointed out that x86 (and therefore all Win32 systems) handles this without a page fault.
Brian 指出 x86(以及所有 Win32 系统)可以在没有页面错误的情况下处理这个问题。
Yet another cause of page faults is triggering guard pages used for stack growth and copy-on-write, but usually those would not occur without bound. I'm not 100% sure if those would show up as access violations or not, because they will be marked as an access violation on entry to the MMU trap, but are probably handled by the OS page fault handler and not transformed into the user mode (SEH) access violation.
页面错误的另一个原因是触发用于堆栈增长和写时复制的保护页面,但通常这些不会在没有约束的情况下发生。我不是 100% 确定这些是否会显示为访问冲突,因为它们将在进入 MMU 陷阱时被标记为访问冲突,但可能由操作系统页面错误处理程序处理,而不是转换为用户模式 (SEH) 访问冲突。
回答by Ana Betts
Any time a mmap'd section is read, a page fault is generated, which includes whenever you load a DLL. So, loading a DLL doesn't actually read all of the DLL into memory, it only causes it to be faulted in as the code is executed.
任何时候读取一个 mmap 的部分,都会产生一个页面错误,包括每次加载 DLL 时。因此,加载 DLL 实际上并没有将所有 DLL 读入内存,它只会在执行代码时导致它出错。
回答by Dean Harding
You'll see soft page faultswhen memory is being shared between processes. Basically, if you have a memory-mapped file shared between two processes, when the second process loads the memory-mapped file, soft page faults are generated - the memory is already in physical RAM, but the operating system needs to fix up the memory manager's tables so that the virtual memory address in your process points to the correct physical page.
当进程之间共享内存时,您会看到软页面错误。基本上,如果你有一个在两个进程之间共享的内存映射文件,当第二个进程加载内存映射文件时,就会产生软页错误——内存已经在物理内存中,但操作系统需要修复内存管理器的表,以便进程中的虚拟内存地址指向正确的物理页。
Particularly for something like Process Hacker, which is likely injecting code into every running process (in order to collect information) it's likely making quite heavy use of shared memory for doing IPC.
特别是对于像 Process Hacker 这样的东西,它可能会将代码注入每个正在运行的进程(以收集信息),它可能会大量使用共享内存来执行 IPC。
回答by Farzin Zaker
Operating Systems use paging to group items witch should be placed in physical memory and move them between physical memory and shared memory. most of the time, data items witch place in a single page, are related to each other. when data items in a page are not used for a long time, operating system moves it to virtual memory to free some space in physical memory. and then when a page is required witch is in virtual memory, operating system moves it from virtual memory (hard disk) to physical memory. this is Page Fault !
操作系统使用分页对应该放置在物理内存中的项目进行分组,并在物理内存和共享内存之间移动它们。大多数情况下,放置在单个页面中的数据项是相互关联的。当页面中的数据项长时间不使用时,操作系统会将其移动到虚拟内存中以释放物理内存中的一些空间。然后当需要一个页面在虚拟内存中时,操作系统将它从虚拟内存(硬盘)移动到物理内存。这是页面错误!
and remember, different operating systems are different in paging algorithms.
请记住,不同的操作系统在分页算法上是不同的。
回答by Bacon Bits
Resource allocation is a delicate balance between keeping primary storage available for use and preventing needing to go to secondary as much as possible. If a process tries to allocate memory and can't that's usually an exception and sometimes a fatal exception.
资源分配是在保持主存储可用和尽可能避免需要转到辅助存储之间的微妙平衡。如果一个进程试图分配内存但不能,那通常是一个异常,有时是一个致命的异常。
Essentially, you can't keep everything in RAM with no free resources available because when a program starts or asks for more it will crash.
本质上,您不能在没有可用资源的情况下将所有内容都保存在 RAM 中,因为当程序启动或要求更多时,它会崩溃。