内存缺页错误
#b计算机基础/c_计算机系统/b_linux系统/补充
2019年5月5日 下午2:20
2020年5月2日 下午11:14更新
总结:
缺页的功能,不属于linux的独立核心功能。缺页功能的完成依托于进程的调度(缺页中断就会调度另外的进程去找那些你需要的数据)、文件系统(涉及到文件的查找,当然免不了文件系统)
作者列出的两个引起内存缺页的场景,我觉得特别有用。
-
- 1.1.分页模式
- 好处:
- 允许虚存空间远大于实际物理内存大小的情况
- 减少了内存碎片的产生
- 好处:
- 【1.2.缺页错误 】
- 当进程在进行一些计算时,CPU 会请求内存中存储的数据。在这个请求过程中,CPU 发出的地址是逻辑地址(虚拟地址),然后交由 CPU 当中的 MMU 单元进行内存寻址,找到实际物理内存上的内容。若是目标虚存空间中的内存页(因为某种原因),在物理内存中没有对应的页帧,那么 CPU 就无法获取数据。这种情况下,CPU 是无法进行计算的,于是它就会报告一个缺页错误(Page Fault)。
- 缺页的流程:
- 因为 CPU 无法继续进行进程请求的计算,并报告了缺页错误,用户进程必然就中断了。这样的中断称之为缺页中断。在报告 Page Fault 之后,进程会从用户态切换到系统态,交由操作系统内核的 Page Fault Handler 处理缺页错误。
- 【1.3.缺页错误的分类和处理 】
- 分类:
- 硬缺页错误(Hard Page Fault)
- 软缺页错误(Soft Page Fault)
- 基本来说,缺页错误可以分为两类:硬缺页错误(Hard Page Fault)和软缺页错误(Soft Page Fault)。这里,前者又称为主要缺页错误(Major Page Fault);后者又称为次要缺页错误(Minor Page Fault)。当缺页中断发生后,Page Fault Handler 会判断缺页的类型,进而处理缺页错误,最终将控制权交给用户态代码。
- 一:若是此时物理内存里,已经有一个页帧正是此时 CPU 请求的内存页,那么这是一个软缺页错误;
- 于是,Page Fault Hander 会指示 MMU 建立相应的页帧到页的映射关系。这一操作的实质是进程间共享内存——比如动态库(共享对象),比如 mmap 的文件。
- 二:若是此时物理内存中,没有相应的页帧,那么这就是一个硬缺页错误;
- 于是 Page Fault Hander 会指示 CPU,从已经打开的磁盘文件中读取相应的内容到物理内存,而后交由 MMU 建立这份页帧到页的映射关系。
- 区别:
- 不难发现,软缺页错误只是在内核态里轻轻地走了一遭,而硬缺页错误则涉及到磁盘 I/O。因此,处理起来,硬缺页错误要比软缺页错误耗时长得多。这就是为什么我们要求高性能程序必须在对外提供服务时,尽可能少地发生硬缺页错误。
- 补充:
- 除了硬缺页错误和软缺页错误之外,还有一类缺页错误是因为访问非法内存引起的。前两类缺页错误中,进程尝试访问的虚存地址尚为合法有效的地址,只是对应的物理内存页帧没有在物理内存当中。后者则不然,进程尝试访问的虚存地址是非法无效的地址。比如尝试对 nullptr 解引用,就会访问地址为 0x0 的虚存地址,这是非法地址。此时 CPU 报出无效缺页错误(Invalid Page Fault)。操作系统对无效缺页错误的处理各不相同:Windows 会使用异常机制向进程报告;*nix 则会通过向进程发送 SIGSEGV 信号(11),引发 内存转储 。
- 分类:
- 【1.4.缺页错误的原因 】
- 之前提到,物理内存中没有 CPU 所需的页帧,就会引发缺页错误。这一现象背后的原因可能有很多。
- 情况1:
- 例如说,进程通过 mmap 系统调用,直接建立了磁盘文件和虚拟内存的映射关系。然而,在 mmap 调用之后,并不会立即从磁盘上读取这一文件。而是在实际需要文件内容时,通过 CPU 触发缺页错误,要求 Page Fault Handler 去将文件内容读入内存。
- 情况2:
- 又例如说,一个进程启动了很久,但是长时间没有活动。若是计算机处在很高的内存压力下,则操作系统会将这一进程长期未使用的页帧内容,从物理内存转储到磁盘上。这个过程称为换出(swap out)。在 *nix 系统下,用于转储这部分内存内容的磁盘空间,称为交换空间;在 Windows 上,这部分磁盘空间,则被称为虚拟内存,对应磁盘上的文件则称为页面文件。在这个过程中,进程在内存中保存的任意内容,都可能被换出到交换空间:可以是数据内容,也可以是进程的代码段内容。
- 1.1.分页模式
2.观察缺页错误 .
-
- 多名组内成员共享一台调研机器
- 一方面,因为公用机器的人很多,必然造成内存压力大,从而存在大量换出的内存;
- 另一方面,新启动的进程,会逐帧地扫描文件;
- 这样一来,新启动的进程,就必须在极大的内存压力下,不断逼迫系统将其它进程的内存换出,而后换入自己需要的内存,不断进行磁盘 I/O;
- 故此,新启动的进程会耗费大量时间进行不必要的磁盘 I/O。
- 多名组内成员共享一台调研机器