Linux之Kernel(1)系统基础理论(6)
Author: Once Day Date: 2025年3月10日
一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦...
漫漫长路,有人对你微笑过嘛...
全系列文章可参考专栏: Linux内核知识_Once-Day的博客-CSDN博客
参考文章:
文章目录
- Linux之Kernel(1)系统基础理论(6)
-
-
-
- [1. 虚拟内存基本概念](#1. 虚拟内存基本概念)
-
- [1.1 传统内存管理方式](#1.1 传统内存管理方式)
- [1.2 局部性原理](#1.2 局部性原理)
- [1.3 虚拟存储器](#1.3 虚拟存储器)
- [2. 请求分页管理方式](#2. 请求分页管理方式)
-
- [2.1 请求分页实现](#2.1 请求分页实现)
- [2.2 页框分配](#2.2 页框分配)
- [2.3 页面置换算法](#2.3 页面置换算法)
- [2.4 抖动和工作集](#2.4 抖动和工作集)
- [2.5 虚拟存储器性能影响因素](#2.5 虚拟存储器性能影响因素)
-
-
1. 虚拟内存基本概念
1.1 传统内存管理方式
传统存储管理方式主要包括连续分配和非连续分配两大类。连续分配又分为单一连续分配、固定分区分配和动态分区分配;非连续分配则包括基本分页存储管理、基本分段存储管理和段页式存储管理。
传统存储管理方式有以下两个主要特征:
-
一次性,作业必须一次性全部装入内存后才能开始运行。这种方式存在两个问题:
(1)当作业体积很大,超过了可用内存空间时,该作业将无法运行。这限制了单个作业的最大尺寸。
(2)当多个作业同时要求运行时,由于内存空间有限,只能让少数作业先运行,其他作业需要等待。这导致了多道程序并发度的下降,降低了系统的整体效率。
-
驻留性:作业一旦被装入内存,就会一直驻留在内存中,直到作业执行结束。在作业运行过程中,即使部分程序或数据暂时用不到,也会一直占据内存,不能换出。当作业因等待I/O而被阻塞时,被占用的内存也不能腾出给其他作业使用。
由此可见,传统存储管理方式存在明显的缺陷。在作业运行过程中,不用或暂时不用的程序和数据会占据大量宝贵的内存空间,而一些亟需运行的作业却可能因内存不足而无法装入。这导致内存利用率低下,降低了系统的整体性能。
为了克服传统存储管理的缺点,后来发展出了一些更先进的内存管理技术,比如虚拟存储技术。它允许作业分多次调入内存,暂时用不到的部分可以换出到外存,从而打破了作业必须全部常驻内存的限制。虚拟存储极大地提高了内存利用率,使得更多作业可以并发执行,显著提升了系统性能。
1.2 局部性原理
局部性原理是计算机系统中一个重要的概念,它是高速缓存技术(如快表、页高速缓存和虚拟内存等)得以实现的理论基础。局部性原理描述了程序在执行过程中对存储器的访问呈现出局部化的倾向性,具体表现为时间局部性和空间局部性两个方面。
(1)时间局部性是指程序中的某条指令执行后,不久的将来该指令很可能再次执行;同样,某个数据被访问过后,不久之后该数据很可能再次被访问。产生时间局部性的主要原因是程序中存在大量的循环结构。在循环过程中,同一条指令会被重复执行多次,同一批数据也会被反复访问。
(2)空间局部性是指一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很可能被访问到。也就是说,程序在一段时间内所访问的存储地址,很可能集中在一定的范围之内。产生空间局部性的原因主要有两点:
-
指令通常是顺序存放、顺序执行的。在程序执行过程中,指令地址的变化多数是连续的,即在访问了某条指令后,紧接着就会访问其相邻的后续指令。
-
数据通常以向量、数组、表等形式聚集存储。当某个数据被访问时,与其相邻的数据项不久后也很可能被访问到。
基于局部性原理,可以用较小的高速缓存来存储近期访问过的指令和数据,从而大幅提高对存储器的访问效率。当CPU需要访问某条指令或某个数据时,首先在高速缓存中查找,如果恰好缓存中已经存在(即"命中"),就可以直接从高速缓存中读取,避免了访问主存的长周期开销。只有当高速缓存未命中时,才需要访问主存。由于局部性原理的存在,高速缓存的命中率很高,大部分访存操作都能在高速缓存中完成,从而显著改善了系统性能。
1.3 虚拟存储器
虚拟存储器(Virtual Memory)是一种存储器管理技术,它使得程序在执行时无需将全部代码和数据一次性装入内存,而是允许被分成多次调入,且在内存空间不足时将暂时用不到的部分换出到外存,从而在逻辑上扩大了内存的容量,使用户看到的内存容量远大于实际的物理内存容量。
虚拟存储器的主要特征包括:
- 多次性:作业在运行时无需一次性全部装入内存,而是可以分成多次调入。
- 对换性:作业在运行过程中,无需一直常驻内存,而是允许被换入、换出。
- 虚拟性:从逻辑上扩充了内存的容量,用户看到的内存容量比实际物理内存大得多。
虚拟内存技术的实现需要建立在离散分配的内存管理方式基础之上,常见的实现方式有:
- 请求分页存储管理
- 请求分段存储管理
- 请求段页式存储管理
当程序访问的信息不在内存时,操作系统会负责将所需信息从外存调入内存(请求调页);当内存空间不足时,操作系统又会将暂时用不到的信息换出到外存(页面置换),从而保证程序的正常运行。
虚拟内存的实现离不开硬件的支持,主要包括:
- 需要一定容量的内存和外存。
- 页表机制(或段表机制)作为主要的数据结构,用于记录页面或段在内存和外存中的存储位置等信息。
- 中断机构,当程序访问的数据或代码尚未调入内存时,将触发中断,由操作系统处理调页请求。
- 地址变换机构,负责将程序中的逻辑地址转换为实际的物理地址。
虚拟内存技术的优点在于,它提供了一个比物理内存更大的虚拟空间,程序可以像处理一个大内存一样来编写,降低了内存管理的复杂度。此外,虚拟内存还具有自动覆盖的功能,程序无需再关注覆盖和对换问题,大大方便了程序的编写。虚拟内存也实现了更好的内存保护,不同进程拥有各自独立的虚拟地址空间,可有效避免不同进程之间的内存侵占。
2. 请求分页管理方式
2.1 请求分页实现
请求分页管理是目前最常用的虚拟存储器实现方式,它在基本分页系统的基础上增加了请求调页和页面置换功能,从而支持虚拟内存。
在请求分页系统中,为了支持部分页面不在内存的情况,在页表项中新增了四个字段:
- 状态位§:标识该页是否已调入内存,供程序访问时参考。
- 访问字段(A):记录本页在一段时间内被访问的次数或上次访问到现在的时间,供置换算法选择换出页面时参考。
- 修改位(M):标识该页在调入内存后是否被修改过,决定换出时是否需要写回外存。
- 外存地址:指出该页在外存上的物理块号,供调页时使用。
在请求分页中,当要访问的页面不在内存时,会触发一个缺页中断,请求操作系统将所需页面调入内存。缺页中断的处理过程如下:
- 将产生缺页的进程阻塞,直到调页完成后再唤醒。
- 若内存中有空闲块,则为要调入的页面分配一个块;否则使用页面置换算法淘汰一个页面,若被淘汰页修改过,则要先写回外存。
- 将所需页面装入分配的内存块,并修改页表中相应表项。
缺页中断与一般中断的区别在于它是在指令执行期间(而非之后)发生的,属于内部异常。一条指令执行期间可能产生多次缺页中断。
请求分页的地址变换在基本分页机制的基础上,增加了缺页中断的处理和页面置换等功能,流程如下(红框为新增步骤):

- 根据页号查询页表,判断所需页面是否在内存:
- 若在内存,且访问类型与页表项权限匹配,则执行第4步;
- 若不在内存,则触发缺页中断,转第2步;
- 若在内存,但访问类型与页表项权限不符,则产生访存失败中断。
- 阻塞引起缺页的进程,保留CPU现场。若有空闲内存块则分配,否则用页面置换算法选择一个换出页面,换出页若有修改则写回外存。
- 将所需页面调入内存,修改页表项并写入快表。若有换出页,相应页表项也要写回慢表。
- 页号与块号拼接成物理地址,执行本次访存。若为写操作,还需置相应页表项的修改位。
由此可见,请求分页管理引入了不少开销,尤其是缺页异常处理和页面调度的I/O操作。为尽量减少缺页,需要合理设置内存工作区和虚存容量,并采用优秀的页面置换算法。此外,通过快表等减少页表访问的次数,也是提高效率的重要手段。
2.2 页框分配
页框分配是请求分页存储管理中的一个重要策略,它决定了如何为进程分配物理内存页框资源。根据不同的分配策略,可以将其分为固定分配和可变分配两种方式。同时,在发生缺页时进行页面置换,也有局部置换和全局置换两种策略。
(1)在固定分配方式下,操作系统会为每个进程分配一组固定数目的物理页框,并在进程运行期间保持不变。这意味着进程的驻留集大小是恒定的。当进程发生缺页时,只能从该进程已分配的页框中选择一个页面进行置换。这种方式实现简单,但可能会导致一些进程分配到的页框数量不足,而另一些进程却有多余的页框,降低了内存利用率。
(2)可变分配方式更加灵活,操作系统初始会为每个进程分配一定数量的页框,但在进程运行过程中,可以根据进程的实际需求动态调整其驻留集大小。当进程频繁缺页时,可以增加分配给它的页框数;而当进程缺页率较低时,可以适当减少分配的页框,回收给其他进程使用。可变分配充分考虑了进程的动态特性,能提高内存的利用效率。
(3)局部置换与全局置换,局部置换策略规定,当一个进程发生缺页时,只能从该进程自己的物理页框中选择一个页面进行置换。而全局置换策略在发生缺页时,可以从操作系统的空闲页框中分配新的页框给进程,也可以将别的进程持有的物理页框换出到外存,再分配给缺页进程。可以看出,全局置换较局部置换有更大的选择空间,理论上有利于提高内存利用率和系统吞吐量。
综合考虑分配策略和置换策略,可以得到三种常见的页框分配组合方案:
- 固定分配局部置换:为每个进程分配固定数目的物理页框,缺页时只能换出自己的页面。这是最简单和传统的方案。
- 可变分配全局置换:初始分配一定的页框,之后可动态调整,缺页时可置换任意进程的页面或分配空闲页框。这种方案理论性能最优。
- 可变分配局部置换:初始分配一定的页框,可动态调整,但缺页时只能换出自己的页面。这是一种折衷的方案。
在采用固定分配策略时,操作系统需要决定如何将系统中的空闲物理块分配给各个进程。常见的算法有:
- 平均分配算法:将所有可供分配的物理块平均分给各个进程,每个进程获得相等数量的物理块。这种方法实现简单,但未考虑进程的特点和需求。
- 按比例分配算法:根据进程的大小按比例分配物理块。进程越大,分配到的物理块就越多。这种方法能够较好地适应不同大小进程的需求。
- 优先权分配算法:根据进程的优先级分配物理块。通常把可分配的物理块分为两部分,一部分按比例分配,另一部分按优先级分配,保证重要和紧迫的进程能够获得更多的资源。
调入页面是指将所需的页面从外存调入内存的过程。根据调入时机的不同,可以分为:
- 预调页策略:在进程运行之前,预先将可能访问到的页面调入内存。这主要用于进程的首次调入,由程序员指定需要预调的页面范围。预调页虽然会占用更多内存,但能减少缺页的发生。
- 请求调页策略:进程在运行过程中,只有当访问的页面不在内存时才发出调页请求。系统此时再将所需页面调入内存。请求调页每次只调入一页,可能会增加缺页的频率,但更加灵活和实际。
在请求分页系统中,外存通常被分为文件区和对换区两部分。当发生缺页时,系统需要决定从哪里调入所需的页面:
-
当系统有足够的对换区空间时,所有需要的页面都可以从对换区调入,因为对换区采用连续分配,读写速度更快。但这需要在进程运行前将相关的文件从文件区复制到对换区。
-
当系统对换区空间不足时,不会被修改的文件可以直接从文件区调入。而可能被修改的部分,在换出时需要写到对换区,下次需要时再从对换区调入。
-
在UNIX系统中,进程运行前相关数据都在文件区。未使用过的页面从文件区调入;使用过需要换出的页面写回对换区,下次从对换区调入。多个进程请求的共享页面若已在内存中,则无需再从对换区调入。
缺页中断是调页过程的关键,具体步骤如下:
- 当进程访问的页面不在内存时,向CPU发出缺页中断。
- 操作系统接收到中断,转入缺页中断处理程序,通过查找页表确定需要调入的页面。
- 若内存未满,则启动I/O将所缺页面调入内存,并修改页表相关信息。
- 若内存已满,则根据页面置换算法选择一页换出。若该页被修改过,则需要先写回外存。
- 页面调入完成后,修改页表项,置存在位为1,表示该页已在内存中。
- 进程重新执行产生缺页的指令,利用修改后的页表形成物理地址,完成访存。
2.3 页面置换算法
本章引用自:【王道】操作系统 知识点总结(合集)【超详细!】 - Zyyyyyyyyy - 博客园
进程运行时,若其访问的页面不在内存中而需将其调入,但内存已无空闲空间时,就需要从内存中调出一页程序或数据,送入磁盘的对换区,选择调出页面的算法就称为页面置换算法。
(1)最佳置换算法(OPT):选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。

但由于人们目前无法预知进程在内存下的页面中哪个是未来最长时间内不再被访问的,因而该算法无法实现。
(2)先进先出置换算法(FIFO):优先淘汰最早进入内存的页面,即在内存中驻留时间最久的页面。

该算法实现简单,只需把调入内存的页面根据先后次序链接成队列,设置一个指针总指向最早的页面。
Belady异常一一当为进程分配的物理块数增大时,缺页次数不减反增的异常现象。只有FIFO算法回产生Belady异常,算法性能差。该算法与进程实际运行时的规律不适应,因为在进程中,有的页面经常被访问。
(3)最近最久未使用置换算法(LRU):选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。

该算法为每个页面设置一个访问字段,来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。
该算法的实现需要专门的硬件支持,虽然算法性能好,但是实现困难,开销大。
(4)时钟置换算法(CLOCK)/最近未用算法(NRU):
简单的CLOCK算法实现方法:
- 为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列。
- 当某页被访问时,其访问位置为1。
- 当需要淘汰一个页面时,只需检查页的访问位。如果是0,就选择该页换出;如果是1,则将它置为0,暂不换出,继续检查下一个页面,
- 若第一轮扫描中所有页面都是1,则将这些页面的访问位依次置为0后,再进行第二轮扫描(第二轮扫描中一定会有访问位为0的页面,因此简单的CLOCK算法选择一个淘汰页面最多会经过两轮扫描)

(5)改进型的时钟置换算法
简单时钟问题:简单的时钟置换算法仅考虑到一个页面最近是否被访问过。事实上,如果被淘汰的页面没有被修改过,就不需要执行I/O操作写回外存。只有被淘汰的页面被修改过时,才需要写回外存。
因此,除了考虑一个页面最近有没有被访问过之外,操作系统还应考虑页面有没有被修改过。在其他条件都相同时,应优先淘汰没有修改过的页面,避免I/O操作。这就是改进型的时钟置换算法的思想。
修改位=0,表示页面没有被修改过:修改位=1,表示页面被修改过。
2.4 抖动和工作集
抖动(Thrashing)问题,抖动指的是在页面置换过程中,刚刚换出的页面马上又要换入主存,刚刚换入的页面又马上要换出主存的现象。它是由于系统中同时运行的进程过多,导致分配给每个进程的物理内存块太少,不能满足进程运行的最低要求,使得进程在运行过程中频繁产生缺页中断而引起的。抖动会带来以下危害:
- 大量进程阻塞在请求调页的等待队列中,增加系统开销
- 频繁的页面调度会大量占用磁盘I/O,磁盘利用率急剧升高
- 进程把大量时间耗费在缺页异常的处理上,CPU利用率急剧下降
因此抖动会使系统的性能严重下降,甚至使系统基本失去工作能力。避免抖动需要合理控制并发进程数,给每个进程分配足够的物理内存。
工作集(Working Set),工作集是指在某段时间间隔内,进程要访问的页面集合。根据程序局部性原理,可以用最近一段时间内进程访问过的页面来预测将来一段时间内进程可能访问的页面。
工作集用W(t, Δ)表示,其中t为当前时刻,Δ为工作集窗口大小。某一时刻进程的工作集就是在过去Δ时间内进程访问过的所有页面的集合。
假设有进程访问页面的序列如下:
yacas
1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5
^ ^
t1 t2
若窗口Δ=5
,则该进程在t1时刻的工作集W(t1, 5) = {2,3,5}
,在t2时刻的工作集W(t2, 5) = {1,2,3,4}
。
工作集的大小一般远小于分配给进程的物理页面数(即驻留集),否则就可能频繁缺页。所以通常要求进程的驻留集大小要大于等于它的工作集大小,才能保证进程正常高效运行。
操作系统可以跟踪进程的工作集大小变化,动态调整分配的物理页面数。当工作集增大时及时增加分配的页面,工作集减小时适当减少分配的页面,把富余页面分配给其他进程,提高内存利用率。这就是工作集页面置换算法的基本思想。
2.5 虚拟存储器性能影响因素
页面大小是影响虚拟存储器性能的重要因素之一。根据局部性原理,页面较大时,发生缺页的概率较低;页面较小时,缺页率则较高。这是因为:
- 页面较小时,可以减少内存碎片,提高内存利用率。但页面过小会导致每个进程拥有大量页面,从而使页表变得冗长,占用大量内存空间。
- 页面较大时,可以有效减少页表的长度,节省内存。但页内碎片会相应增加,降低内存利用率。
因此,页面大小需要在降低缺页率和减少碎片之间寻求平衡。通常可以根据系统的物理内存容量、进程特点等因素来确定最优的页面大小。
分配给进程的物理内存块数量直接影响着缺页率。物理块数越多,进程在执行过程中所需的页面就越有可能已经在内存中,从而降低缺页率。但需要注意的是,当物理块数增加到一定程度后,继续增加物理块对缺页率的改善效果会变得不明显。因此,物理块的分配也需要在提高性能和节省内存之间权衡。
页面置换算法的目标是在内存不足时,选择换出最合适的页面,为即将装入的页面腾出空间。一个好的置换算法应当尽量将未来可能被访问到的页面保留在内存中,从而降低缺页率,提高访问速度。
常见的页面置换算法包括:
- 最近最少使用(LRU)算法:总是淘汰最长时间未被使用的页面。
- 时钟(CLOCK)算法:考察未使用时间和访问频率,优先替换访问位为0的页面。
- 最不常用(LFU)算法:总是淘汰访问频率最低的页面。
不同的置换算法在不同场景下的表现各异。通过选择适合的算法,可以有效提高虚拟存储器性能。
当被置换出的页面内容发生过修改时,需要将其写回磁盘,以保证数据一致性。但频繁的磁盘写操作会严重影响性能。为此,可以采取暂不写回策略,将这些页面挂在一个"脏页面链表"上,直到数量达到某个阈值,再批量写回磁盘。合理的写回策略可减少磁盘IO次数,提高整体效率。
程序的内存访问局部性,即程序在一段时间内频繁访问某些内存区域的特性,是影响缺页率的内在原因。程序局部性越好,说明大部分内存访问都能命中少数页面,缺页率自然较低。
为了提高局部性,可采取以下措施:
- 优化程序的数据布局,避免跨页访问。比如数据集中存储在数组,而不是链表。
- 提高循环访问的步长。顺序访问比随机访问更有利于利用局部性。
- 程序逻辑上相关的模块尽量存储在相邻的页面。
另外,存储数据结构的方式也会影响局部性。例如对于按行存储的矩阵,按行访问比按列访问更加高效,因为前者局部性更佳。
率。

Once Day
也信美人终作土,不堪幽梦太匆匆......
如果这篇文章为您带来了帮助或启发,不妨点个赞👍和关注,再加上一个小小的收藏⭐!
(。◕‿◕。)感谢您的阅读与支持~~~