本次会议围绕操作系统课程中内存管理、页表、进程创建与切换等内容展开详细讲解,介绍了多种内存管理算法、页表结构与地址转换、进程创建机制及系统内存策略,并探讨了内存优化方案,内容如下:
-
内存管理算法回顾与分析
-
虚拟内存与页表
-
虚拟内存概念:宫晓利指出,操作系统为程序员构造巨大的虚拟地址空间,使用页表管理,该空间部分分配物理内存,部分未分配,形成虚拟内存。当程序访问时,才真正分配物理内存。
-
页表分级与结构:32 位系统页表项数众多,需进行分级,采用二阶的 B + 树管理,每个配置 frame 为 4K。该结构对计算机界影响深远,虽 64 位系统下有局限性,但为保证兼容性,页大小仍多为 4K。
-
页面置换算法
-
FIFO 算法问题:FIFO 算法(先进先出)曾受硬件开发人员好评,但贝莱迪指出其存在缺陷,可能出现资源增加但程序运行变慢的情况。
-
OPT 算法:OPT 算法(最优置换算法)由贝莱迪提出,在可预测未来的情况下能得到最优解,但实际难以实现。
-
LRU 与 LFU 算法局限:LRU(最近最少使用)和 LFU(最不经常使用)算法可减少 refault 数量,但实现复杂度高,对硬件要求大。
-
时钟算法及改进:时钟算法通过周期性扫描页表项的 access bit 和 dirty bit 来选择置换页面。初级版本简单粗暴,2020 年前后改进为 MG LRU(Multi generation LRU),通过 aging 指针记录页面衰老程度,提高预测准确性。
-
多进程内存分配算法
-
工作集算法:工作集描述进程在一段时间内访问的页面集合,工作集算法根据页面访问时间决定是否置换,以实现内存动态分配,但在实际中难以实现。
-
缺页率算法:缺页率算法通过观察系统缺页次数推断内存分配情况,在缺页时顺便清理长时间未访问的页面,避免无意义的内存扫描。该算法在 2022 年的 Osplos 顶会论文中被提及,用于判定系统内存压力。
-
页表与地址空间详解
-
页表记录内容
-
物理地址记录:宫晓利强调,页表是给 MMU 使用的,因此记录的是物理地址。CPU 使用虚拟地址,由 MMU 将其翻译成物理地址。
-
地址转换过程:操作系统构建页表时使用虚拟地址,需通过特定公式将其转换为物理地址。在系统启动时,操作系统获取物理内存信息,构建页表后开始使用虚拟地址。
-
系统中的页表数量与作用
-
物理内存管理表:操作系统创建一个链表或其他数据结构管理所有可分配的物理内存,如 minicore 中的配置 list 和 Linux 中的 Folio。
-
进程页表:每个进程有独立的虚拟地址空间,对应一个页表,用于完成虚拟地址到物理地址的翻译。
-
缺页处理表:每个进程还有一个 Maps 表,记录虚拟地址空间的布局,辅助操作系统处理缺页中断。
-
进程间的可见性与切换
-
进程可见性:两个进程是否能看见对方取决于它们的页表是否指向同一个叶节点。
-
进程切换:进程切换时,不仅要更换上下文和寄存器,还要更换页表。通过修改 MMU 的 SATP 寄存器指向新的页表树根,实现地址空间的切换。
-
进程创建与切换机制
-
进程创建方式
-
fork 调用:Linux 系统中,通过 fork 调用以当前进程为副本创建新进程。新进程与原进程数据、指令和上下文相同,但 fork 函数返回值不同,用于区分两个进程。
-
exec 调用:exec 调用用于让当前进程执行已编译好的二进制程序,重新构造进程的虚拟地址空间。
-
进程复制机制
-
半深半浅拷贝:操作系统在创建新进程时,采用半深半浅拷贝,只复制分支节点,页节点共享,以减少不必要的数据复制。
-
写实复制:为避免共享页节点带来的问题,采用写实复制机制,将页面设为只读,当发生写操作时再复制页面。
-
进程创建细节分析
-
页表复制问题:对于多级页表,中间分支节点也可采用写时复制,避免无脑复制。2022 年 user sys 顶会文章对此进行了探讨。
-
资源浪费问题:若 fork 后立即执行 exec,完整复制页表会导致资源浪费,因此选择半深半浅拷贝。
-
系统内存策略与实现细节
-
Linux 系统水位线机制
-
水位线作用:Linux 系统通过水位线机制保证系统有足够的空闲页,避免频繁的磁盘读写操作。
-
内存回收过程:当空闲页数量低于低水位线时,启动线程回收长时间未访问的页面;若水位线继续下降到 min 位置,可能导致系统死机。
-
内存回收与进程退出处理
-
OOM killer 机制:当内存回收机制无法正常工作时,OOM killer 机制会杀死占用内存多的进程,释放资源。
-
进程退出回收:进程退出时,由父进程调用 wait 函数回收子进程的资源。若无人回收,进程会变成僵尸进程或孤儿进程,系统中有僵尸进程收集器负责回收其资源。
-
进程上下文切换细节
-
TLB 处理:进程上下文切换时,TLB 应清空,因为页表已更换。
-
CACHE 处理:进程上下文切换时,CACHE 清空与否存在争议。由于 CACHE 命中率高,直接丢弃可惜,但目前暂无更好的处理方法。
-
多进程与内存压力问题
-
多进程对 CPU 利用率的影响
-
前期提升:在进程数量较少时,多进程并发执行可提高 CPU 利用率。
-
后期抖动:当进程数量过多,每个进程需要的内存增加,会频繁触发缺页异常,导致 CPU 利用率下降,出现抖动现象。
-
内存压力解决方案
-
数据上传网络:在网速足够快的情况下,可将内存数据上传到网络,减少对本地磁盘的依赖。
-
zram 压缩技术:使用 zram 技术将不活跃的内存压缩存储,节省内存空间。但该技术在解压缩时可能存在问题,需要合适的算法支持。
-
鸿蒙系统改进:鸿蒙系统在多核处理器上采用并行压缩算法,提高 swap 速度;修改内存分配接口,根据内存重要性进行回收,提升内存使用率。
-
段机制与页机制对比
-
段机制概念与优势
-
段机制设想:段机制将程序区域切分成片段,按片加载到内存中,通过段控制器(SMU)进行寻址,类似于页机制,但每个段长度可灵活设置。
-
优势分析:段机制可将相似属性的程序和数据放在一起,提高执行效率,曾受到硬件设计者和软件人员的关注。
-
段机制未广泛应用原因
-
硬件支持不足:除 80386 系列处理器外,其他处理器大多只支持页机制,缺乏对段机制的硬件支持。
-
系统复杂度增加:Linux 等开源操作系统为实现跨平台兼容性,选择只使用页机制,避免增加系统复杂度。