虚拟内存讲解
三、内存管理
内存管理是操作系统内核的核心功能之一,核心目标是对物理内存资源进行统一分配、调度与回收。在多进程并发的场景下,它需要解决内存隔离、地址转换、内存利用率提升、容量逻辑扩充等核心问题,同时保障系统稳定性与进程间的内存安全。
现代通用操作系统几乎都以虚拟内存作为内存管理的核心基石,通过软硬件结合的方式,为每个进程构建独立的虚拟地址空间,彻底屏蔽物理内存的底层细节。
3.1 虚拟内存
虚拟内存
1. 核心定义
虚拟内存是一种经典的内存管理技术:它为每个进程提供一个独立、连续、私有的虚拟地址空间,让进程产生 “自己独占全部系统内存” 的错觉;操作系统通过地址映射机制,将虚拟地址转换为真实的物理内存地址,同时可将不常用的内存数据暂存到磁盘交换区,从逻辑上扩充内存容量。
2. 产生背景与解决的核心问题
早期直接分配物理内存的模式存在致命缺陷:
- 进程直接操作物理地址,可随意篡改其他进程甚至内核的数据,无安全性可言
- 多进程并发时地址冲突严重,无法同时运行多个程序
- 连续分配会产生大量外部碎片,内存利用率极低
- 体积大于物理内存的程序无法直接运行
虚拟内存机制从根本上解决了上述所有问题。
3. 四大核心特性
- 地址隔离:每个进程拥有独立的虚拟地址空间,进程无法访问其他进程的地址空间,彻底避免非法篡改,保障系统稳定性
- 逻辑扩充:利用磁盘空间作为内存后备存储,程序运行时仅加载必要部分到物理内存,其余暂存磁盘,逻辑上扩大了可用内存
- 地址透明:程序员无需关心物理内存的实际地址与分布,只需基于虚拟地址编程,地址转换由操作系统 + CPU 硬件自动完成
- 离散分配:进程的内存可以离散地分布在物理内存中,无需连续大块空间,大幅降低内存碎片
4. 实现基础
- 硬件基础:CPU 中的内存管理单元(MMU),专门负责虚拟地址到物理地址的高速转换
- 理论基础:程序的局部性原理
- 时间局部性:刚被访问的数据,短时间内大概率会被再次访问
- 空间局部性:刚被访问的数据附近的内存区域,大概率会很快被访问 正因为局部性,系统只需将程序的一小部分装入内存,即可保证程序正常运行。
内存分段
1. 设计思想
内存分段是基于程序的逻辑结构进行内存划分的管理方式。程序天然由多个独立的逻辑模块组成(代码、数据、栈、堆等),分段机制就是按照逻辑含义,将虚拟地址空间划分为若干长度不等的 “段”,每个段拥有独立的段名、起始地址、长度和访问权限。
2. 常见段分类
- 代码段(.text):存放程序执行指令,属性为只读、可执行
- 数据段(.data):存放已初始化的全局变量和静态变量,属性为可读可写
- BSS 段:存放未初始化的全局变量,程序加载时统一初始化为 0
- 堆段:动态内存分配区域,由低地址向高地址增长
- 栈段:存放函数调用栈、局部变量、函数参数,由高地址向低地址增长
3. 段表与地址转换
操作系统为每个进程维护一张段表,记录每个段的段号、物理段基址、段长度、访问权限等信息。
地址转换完整流程:
- 虚拟地址被硬件拆分为「段号 + 段内偏移量」两部分
- 根据段号索引段表,获取该段的物理基址和段长度
- 执行越界检查:若段内偏移量 > 段长度,触发内存越界中断,程序终止
- 检查通过后,最终物理地址 = 段基址 + 段内偏移量
4. 优缺点
- 优点
- 贴合程序的逻辑结构,便于模块化编程与代码理解
- 以逻辑段为单位进行内存共享和保护,粒度合理,例如代码段可被多个进程共享
- 支持段的动态增长,适配栈、堆等按需扩展的场景
- 缺点
- 段长度不固定,分配与回收后会产生大量外部碎片,内存利用率低
- 内存不足时需将整个段换出到磁盘,I/O 开销大
内存分页
1. 设计思想
内存分页将虚拟地址空间和物理内存都划分为大小完全相等、固定尺寸的连续小块:虚拟空间的小块称为页(Page),物理内存的小块称为页框(Page Frame,物理页)。
系统以页为最小单位进行内存分配,进程的虚拟页可以离散映射到任意物理页框中,无需连续的物理内存。主流系统默认页大小为 4KB。
2. 页表与地址转换
操作系统为每个进程维护一张页表,记录每个虚拟页号与物理页框号的映射关系,同时附带有效位、修改位、访问权限等标志位。
地址转换完整流程:
- 虚拟地址被拆分为「虚拟页号 + 页内偏移量」,偏移量位数由页大小决定
- 根据虚拟页号索引页表,读取对应的物理页框号
- 若有效位为 0,说明该页不在物理内存中,触发缺页中断;操作系统从磁盘加载对应页面到物理内存,更新页表后重新执行指令
- 检查通过后,最终物理地址 = 物理页框号 × 页大小 + 页内偏移量
3. 快表(TLB)
页表存放在物理内存中,一次地址转换需要两次内存访问(先查页表、再访问数据),性能损耗较大。 CPU 中集成了转译后备缓冲区(TLB,俗称快表),它是高速缓存,存放最近最常用的「虚拟页号 - 物理页框号」映射关系。
- TLB 命中:直接获取物理页框号,无需访问内存页表,速度极快
- TLB 未命中:再访问内存中的页表,同时将该映射更新到 TLB 中
4. 多级页表
单级页表在大地址空间下会占用海量连续内存(32 位系统 4KB 页下,单进程页表可达 4MB)。多级页表的核心思想是对页表本身再分页,未使用的页表项无需分配内存,大幅节省空间。
以经典二级页表为例,虚拟地址拆分为:「页目录号 + 页表号 + 页内偏移量」
- 一级页表(页目录表):记录二级页表的物理地址
- 二级页表:记录每个虚拟页对应的物理页框号
5. 页面置换算法
当物理内存占满且发生缺页中断时,系统需要淘汰一个内存中的页面,腾出空间加载新页。经典算法如下:
- 最佳置换算法(OPT):淘汰未来最久不使用的页面,理论性能最优,但无法实际实现,仅作为性能基准
- 先进先出算法(FIFO):淘汰最早进入内存的页面,实现简单,但存在 Belady 异常(分配物理页增多,缺页率反而上升)
- 最近最久未使用算法(LRU):淘汰过去最长时间未被访问的页面,性能接近 OPT,但硬件 / 软件实现成本高
- 时钟置换算法(CLOCK):通过访问位循环扫描淘汰页面,是 LRU 的低成本近似实现,广泛应用于实际系统
6. 优缺点
- 优点
- 页大小固定,内存管理简单,几乎消除外部碎片,仅存在少量内部碎片
- 以页为单位换入换出,粒度小,磁盘 I/O 开销低
- 离散分配,内存利用率远高于分段机制
- 缺点
- 页是纯物理划分单位,不贴合程序逻辑结构,不便于按逻辑模块共享与保护
- 多级页表会增加地址转换的内存访问次数,必须依赖 TLB 优化性能
段页式内存管理
1. 设计思想
段页式管理结合了分段与分页的优势:先将进程按逻辑结构分段,再将每个段内部划分为固定大小的页。既保留了分段 “逻辑模块化、易于共享保护” 的优点,又拥有分页 “内存利用率高、碎片少” 的特点。
2. 地址转换流程
虚拟地址结构为:「段号 + 段内页号 + 页内偏移量」 系统为每个进程维护一张全局段表,每个段对应一张独立的页表。
完整转换步骤:
- 根据段号索引进程段表,获取该段的页表起始地址与段长
- 执行段内越界检查,确认段内页号合法
- 根据段内页号索引该段的页表,获取物理页框号
- 最终物理地址 = 物理页框号 × 页大小 + 页内偏移量
3. 优缺点
- 优点:兼顾分段的逻辑优势与分页的内存效率,段可动态增长,页面换入换出开销小
- 缺点:地址转换需要多次查表,硬件开销大;系统管理复杂度显著上升
Linux 内存管理
Linux 以页式内存管理为核心,结合类段页式的地址空间设计,实现了一套从物理页分配到虚拟地址管理的完整工业级方案。
1. 虚拟地址空间布局
- 32 位系统:共 4GB 虚拟空间,高 1GB 为内核空间,低 3GB 为用户进程空间
- 64 位系统:地址空间极大,用户空间与内核空间彻底分离,中间保留大量空洞区域防止地址越界 用户空间从低地址到高地址依次为:代码段、数据段、BSS 段、堆、内存映射区、栈。
2. 物理内存管理:伙伴系统
Linux 以页为物理内存基本单位,使用 ** 伙伴系统(Buddy System)** 管理连续物理页的分配与回收,解决外部碎片问题。
- 核心逻辑:将物理页按 2 的幂次分组为不同大小的内存块;分配时找到满足需求的最小块,不足则拆分大块;回收时检查相邻的 “伙伴块” 是否空闲,若均空闲则合并为更大的块。
3. 小内存管理:Slab 分配器
伙伴系统以页为单位分配,对于小于一页的高频小内存需求(如内核对象),使用 Slab 分配器。
- 核心逻辑:将内存页划分为不同尺寸的 slab 缓存,专门存放内核中高频创建销毁的对象(进程描述符、文件结构体等),减少分配释放开销,同时降低内部碎片。
4. 页表与页面回收
- 页表:64 位 Linux 采用 4 级页表(PGD、PUD、PMD、PTE),适配超大地址空间,节省页表内存
- 页面回收:采用改进型时钟置换算法,支持 swap 交换分区;匿名页换出到交换区,文件映射页直接回写磁盘后回收
总总结结
- 虚拟内存是现代操作系统内存管理的核心,依托局部性原理与 MMU 硬件,实现了内存隔离、逻辑扩充与地址透明三大核心价值。
- 三种经典内存管理模式对比:
- 分段:按逻辑划分、长度可变,便于共享保护,存在外部碎片
- 分页:固定尺寸划分、内存利用率高,逻辑属性弱
- 段页式:先分段再分页,兼顾两者优势,系统复杂度最高
- 工业级系统(如 Linux)以分页机制为核心,配合多级页表、TLB、伙伴系统、Slab 分配器等机制,在性能、内存利用率与稳定性之间取得平衡。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)