📂 操作系统 - Operating System / Chapter II 虚拟化 / Section 2 内存虚拟化 / 2-2 分段与分页

分页的介绍

2026-05-12
#OS
  • 分页的概念

    • “分段“这一内存管理办法存在一个问题,就是内存空间会碎片化(fragmented)
    • 为了避免这些内存碎片的出现,出现了“分页”这一办法。
    • “分页”并不将进程的地址空间分成几个不同长度的逻辑段(如代码、堆、栈),而是将进程分割为几个固定大小的单元,每个单元成为一
    • 同时,我们把物理内存视作一个定长槽块的阵列,每个槽块叫做“页帧(Page frame)”;我们也给虚拟内存中的每个取名为虚拟内存页
  • 进程与分页

    • 操作系统通过页来维护进程的地址空间

      • 一个进程会拥有一个或多个页
      • 对于进程的虚拟地址,一个虚拟地址会包含虚拟页面号(Virtual page number, VPN)页内偏移量(Offset)
      • 为了记录地址空间的每个虚拟页在物理内存中的位置,操作系统为每个进程各自维护了一个页表,操作系统通过页表来完成从虚拟地址到物理地址的转换(translate)
    • 从虚拟地址到物理地址的转换

      • 页表中存储了每个虚拟页面号物理帧号(PFN, Physical frame number, 也叫”物理页号“)的映射,也就是存储每个虚拟内存页物理内存页帧映射
      • 当进程访问虚拟地址时:
        1. 首先操作系统检查目标虚拟地址的虚拟页面号,通过页表获取其对应的物理帧号
        2. 对于偏移量,物理内存和虚拟内存是一致的
        3. 然后将物理帧号偏移量发送给物理内存,从而完成访问
  • 页表

    • 页表存储在哪里

      • 相较于段表和基址/界限对,页表占用的空间非常大
      • 由于页表太大了,我们不使用MMU来存储页表,而是直接将页表存在内存里
      • 其实操作系统本身也可以有一部分运行在虚拟内存上,所以页表也可以运行在虚拟内存上,甚至实际可能交换到磁盘中,不过在这里先假设页表存储在物理内存上
    • 页表的内容

      • 页表是一个数据结构,用于将虚拟页号映射到物理帧号,每一个单元就是一个页表项(PTE, Page table entry)
      • 实现页表最简单的形式是线性页表(Linear page table),也就是一个数组。操作系统通过虚拟页号作为索引检索数组,找到对应的页表项,并获得期望的物理帧号
      • 每一个页表项中都有很多个部分,或者说很多个
        • 有效位(Valid bit):用于指示这个地址转换是否有效。例如一个进程的代码与堆在地址空间的一端,栈在另一端,它们中间的这一部分就是无效的访问无效部分会陷入操作系统
        • 保护位(Protection bit):表明页是否可以读取、写入或执行。同样,执行不被允许的操作会陷入操作系统
        • 存在位(Present bit):表示该页在物理存储器上,还是它已被换出(Swapped out),在磁盘上
        • 脏位(Dirty bit):表示页被带入内存后是否被修改过
        • 参考位(Reference bit)/访问位(Access bit):用于追踪页是否被访问了。也可以用于表示这个页受不受欢迎,因此应该留在内存中,这对于页面替换(Page replacement) 非常重要
  • 分页的性能

    • 页表不仅占用的空间很大,使用页表也会让速度变慢
    • 对于一个进程,我们需要给它维护一个页表基址寄存器(Page-table base register) 来存储页表的起始位置的物理地址。这意味着对每个内存引用,分页都会需要我们多执行一次内存引用
    • 显然,虽然分页可以避免外部碎片问题(仍然存在内部碎片问题),但是它还需要优化