什么原因导致页面错误?

发布于 2024-11-01 07:57:38 字数 452 浏览 5 评论 0 原文

根据维基百科

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

好吧,这是有道理的。

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

Screenshot

或者换句话说,为什么内存会被调出? (我不知道它是用户内存还是内核内存。)我没有页面文件,RAM 使用量约为 4 GB 中的 1.2 GB,这是在干净重启后的情况。任何资源都不缺;为什么会有东西被调出?

According to Wikipedia:

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?

Screenshot

Or in other words, why is any memory getting paged out? (I have no idea if it's user or kernel memory.) I have no page 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

昔日梦未散 2024-11-08 07:57:38

(我是 Process Hacker 的作者。)

首先:

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

这并不完全正确,正如稍后在同一篇文章中所解释的那样(轻微页面错误)。存在软页面错误,内核需要做的就是将页面添加到进程的工作集中。下面是 Windows Internals 书中的一个表格(我已经排除了导致访问冲突的表格):

故障原因 结果
访问不在内存中但在磁盘上的页面页面文件或映射文件 分配物理页面,并从磁盘读取所需的页面并将其放入相关工作集中
访问备用或修改列表上的页面 将页面转换为相关进程、会话或系统工作集
访问零需求页面 将零填充页面添加到相关工作集
写入写入时复制页面 Make页面的进程私有(或会话私有)副本,并替换进程或系统工作集中的原始

页面错误可能因多种原因而发生,如您在上面所看到的。其中只有一项与从磁盘读取有关。如果您尝试从堆中分配一个块,并且堆管理器分配新页面,然后访问这些页面,您将遇到需求零页面错误。如果您尝试通过写入 kernel32 的页面来挂钩 kernel32 中的函数,您将收到写时复制错误,因为这些页面会被静默复制,因此您的更改不会影响其他进程。

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

(I'm the author of 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):

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.

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).

请你别敷衍 2024-11-08 07:57:38

页面错误的一个缓慢但稳定的来源是操作系统对不常访问的页面的探测。在这种情况下,操作系统会将某些页面标记为不存在,但将它们按原样保留在内存中。如果应用程序访问该页面,则会发生#PF 陷阱,并且操作系统会简单地再次标记该页面,而无需进一步处理。如果“很长一段时间”过去了并且页面从未出现错误,那么操作系统就知道该页面是在需要时进行交换的良好候选者。即使在没有资源压力的情况下,这种机制也可以主动运行。

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.

墨落成白 2024-11-08 07:57:38

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

假设您映射一个日志文件并不断向其追加内容。每次超过提交内存的末尾时,都会发生页面错误,操作系统将为您提供一个新的空页面并调整文件长度。


也可能是程序捕获并处理的访问违规。


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

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

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


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

"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.

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.

Brian pointed out that x86 (and therefore all Win32 systems) handles this without a page fault.


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.

遇见了你 2024-11-08 07:57:38

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

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.

浅浅 2024-11-08 07:57:38

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

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

You'll see soft page faults when 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.

故人如初 2024-11-08 07:57:38

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

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

页面错误的基础知识< /a>

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.

Basics of Page Faults

清旖 2024-11-08 07:57:38

资源分配是保持主存储可用和尽可能防止需要转到辅助存储之间的微妙平衡。如果一个进程尝试分配内存但不能,这通常是一个异常,有时是一个致命异常。

从本质上讲,如果没有可用的免费资源,您就无法将所有内容保留在 RAM 中,因为当程序启动或请求更多资源时,它会崩溃。

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.

执手闯天涯 2024-11-08 07:57:38

让我们了解记忆工作的基础知识。内存有物理地址和逻辑地址。物理地址具有名为帧的块。逻辑地址具有称为页的块。 CPU生成逻辑地址并将其分为两部分,即偏移量和页号。页表由各个页号的索引及其与各个帧号的匹配组成。它将偏移量添加到帧号上,最终给出物理内存中的地址。

表中缺少所需的页号会导致页错误。页面错误的主要原因是物理内存(或主内存)中缺少一块内存或请求位置的内存量不足。意味着一块内存是程序工作集的一部分,但系统无法在物理内存中追踪到它。它是由计算机硬件生成的异常,它告诉操作系统丢失的引用。

内存管理单元(MMU)处理这个过程。现在,页面错误有两种类型,即硬页面错误和软页面错误。

硬页面错误
当所需的页面不在主物理内存中时,就会发生这种情况,因此系统必须从虚拟内存中获取它。有一个与页表中的条目相关联的有效性位。如果发现某些条目的有效性位为零,则表明该页尚未分配任何帧,因此发生页错误。

软页面错误
当要查找的页面在内存中的其他位置找到时,就会发生这种情况。系统找到内存块的实际位置可以是“缓存”。

现在让我们了解页面错误的不同原因。

当您希望访问不驻留在主内存中的页面时,可能会发生页面错误。但是,要访问的内存块位于要从中获取它的虚拟内存中。

当您想要访问属于“备用”模式类别下的页表一部分的页面时,可能会发生页面错误。这意味着该页位于已修改的页表下,并解决此问题;该页面必须传输到正确的会话页表或正确的工作集。

页面错误的发生可能是由于访问零需求页面的做法所致。当您希望从堆内存中分配一个块,并且堆管理器提供新页面,并且当您尝试访问这些页面时,会发生需求零页面错误,就会发生这种情况。

当您尝试通过写入 kernel32 的页面来挂钩 kernel32 中的函数时,会发生写入时复制页面错误。这是因为这些页面被悄悄地复制。因此,对这些的更改不会影响其他进程。

因此,发生页面错误的原因不止一个。

Let us understand the basics of the working of memory. Memory has physical and logical addresses. The physical address has blocks named frames. The logical address has blocks called pages. The CPU generates the logical address and divides it into two parts, namely offset and page number. A page table consists of indexes to respective page numbers and their matching to the individual frame numbers. It adds the offset to the frame number, finally giving the address in the physical memory.

The absence of the required page number in the table gives rise to a page fault. The main reason for page faults is the absence of a piece of memory in the physical memory(or main memory) or the lack of the amount of memory at the requested location. It means that a piece of memory is part of the program's working set, but the system cannot trace it in the physical memory. It is an exception generated by the computer's hardware, which tells the operating system about the missing references.

The memory Management Unit(MMU) handles this process. Now, there are two types of page faults, namely hard page faults and soft page faults.

Hard Page Fault
It occurs when the required page is not in the main physical memory, so the system must fetch it from the virtual memory. There is a validity bit associated with the entries in the page table. If the validity bit is found to be zero for some entry, it indicates that the page has not been assigned any frames, so page fault occurs.

Soft Page Fault
It occurs when the page to be found is found somewhere else in the memory. This actual place where the system finds the piece of memory can be the 'cache.'

Now let us understand the different causes of page fault.

A page fault can occur when you wish to access a page that is not a main memory resident. But, the piece of memory to be accessed is in the virtual memory from where it is to be fetched.

A page fault can occur when you want to access a page that is part of a page table that comes under the 'standby' mode category. It means that the page is under a modified page table, and to solve this; the page has to be transferred to the correct session's page table or the proper working set.

An occurrence of a page fault may be due to the practice of accessing a demand-zero page. It happens when you wish to allocate a block from the heap memory, and the heap manager gives new pages, and when you try to access those pages, a demand-zero page fault occurs.

When you try to hook a function in kernel32 by writing to its pages, a copy-on-write page fault occurs. It is because these pages get copied silently. So, the changes on these do not affect other processes.

So, a page fault occurs for more than one reason discussed above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文