ZKX's LAB

关于Windows页面错误的一些基础概念

2020-12-13新闻5

今天我们会说说关于虚拟内存处理中最为常见的一个问题:页面错误(Page Fault)。

什么情况下会发生一个页面错误呢?

当应用程序请求的页面地址不在当前的内存驻留页面(Memory resident pages)时,就会发生页面错误。

当发生页面错误的时候,会发生什么?

发生页面错误的线程会被操作系统设置为挂起状态,而此时操作系统会尝试在磁盘上找到对应的页面并将此页面恢复到物理内存。

当一个线程尝试引用一个非驻留内存页面时,一个硬件中断会触发并导致应用程序的终止执行。引发页面错误的指令会产生一个地址访问异常,从而触发中断。内核中有一个中断服务例程(ISR, Interrupt Service Routine)会获得控制流,并判断出访问地址是有效的,但是访问地址所在的页面没有驻留在内存中。

接下来,操作系统会在页面文件中定位目标页面的一个拷贝,并将此页面从磁盘拷贝至内存中的一个空闲页面。一旦拷贝操作成功完成,则操作系统会允许上文中提到的挂起线程继续执行。

请注意:如果程序因为逻辑错误而访问一个无效的内存位置,则一个类似于页面错误的地址访问异常会被触发,同时也会引发一个硬件中断。这个时候,内存管理器(Memory Manager)的ISR会获取控制流来区分这两种不同的情况。

区分软页面错误和硬页面错误,也十分重要。

当访问一个不在物理内存或内存映射文件(由应用程序进程创建)中的页面时,一个硬页面错误会被触发。

当系统内存不足或者发生了频繁的硬页面错误时,应用程序的性能会受到影响。所以,从操作系统的角度来看,尽可能迅速地从硬页面错误中恢复过来,从而不影响程序的运行时性能,就显得尤为重要。

另一方面,当访问一个驻留在别处的内存页面时,就会发生一个软页面错误。

举个例子,目标内存页面可能位于另一个进程的工作集中。软页面错误发生的另一种场景是:由于目标页面之前被使用,但它已经从进程的工作集中移除,或者,目标页面由于系统的Prefetch(性能优化组件)而成为驻留页面。

我们还需要快速回顾一下另外两个概念:系统文件缓存(System File Cache)和缓存错误(Cache Faults)。系统文件缓存使用虚拟内存管理器的功能来管理应用程序文件数据。它会映射文件到系统虚拟地址空间的一部分并使用进程的工作集机制来尽可能地保持当前文件在内存中的驻留。

缓存错误也是一种页面错误,当程序引用一个没有驻留在物理内存中的文件时,就会发生缓存错误。操作系统通过从磁盘或者网络中读取对应的文件数据来解决缓存错误。

在很多的文件服务中,文件缓存都大量使用了虚拟内存和物理内存。

最后,当研究和页面错误有关的问题时,区分硬页面错误还是软页面错误很重要。

在性能监视器中,页面错误计数值并没有区分这两种错误,所以,如果想要区分它们,需要做一些额外的工作。

以下几个计数器可以用来分析页面错误:

1) 内存\页面错误/每秒

2) 内存\缓存错误/每秒

3) 内存\页面读取/每秒

前面两个计时器用来追踪工作集和文件系统缓存。页面读取可以用来追踪硬页面错误。

如果你观察到有大量的页面错误,同时伴随着大量的页面读取(也会显示在磁盘计数中),则当系统可用内存不足时就会出现应用程序或者整体计算性能降低的问题。

尽量避免发生硬页面错误,尽量减少软页面错误(例如,频繁的进行堆内存的分配和释放)。

本文来自:The Basics of Page Faults

#电脑使用技巧

qrcode
访问手机版