分页 vs 分段 vs 段页式

一句话:内存管理要解决”怎么把程序塞进内存”的问题。分页是把内存切成等大的格子(像宿舍),分段是按逻辑切成不等大的块(像户型图),段页式是先分段、段里再分页(组合拳)。

一、分页(Paging)——把内存切成格子

先解决一个问题

 
早期操作系统直接把程序加载到内存里跑。
 
问题:
 
  - 程序 A 占用 0~1000
 
  - 程序 B 必须要加载到 1000 以后
 
  - 如果 A 结束了,B 还没加载完,中间空着一块——内存碎片
 
解决方案:分页。
 

分页的核心思想

 
把物理内存切成固定大小的"页框"(4KB 一个格子)
 
把程序的虚拟地址空间也切成同样大小的"页"
 
程序不用占连续的内存,可以散落在各个格子里。
 

graph TD

    subgraph 程序的虚拟地址空间

        V0[页0]

        V1[页1]

        V2[页2]

        V3[页3]

    end

    subgraph 物理内存

        F0[页框0]

        F1[页框1]

        F2[页框2]

        F3[页框3]

        F4[页框4]

        F5[页框5]

        F6[页框6]

        F7[页框7]

    end

    V0 --> F2

    V1 --> F5

    V2 --> F0

    V3 --> F7

 
程序以为自己的页 0~3 是连续的内存。
 
实际物理内存里:页0→框2、页1→框5、页2→框0、页3→框7
 
——到处散落,但程序感觉不到。
 

关键概念:页表

 
程序访问地址 0x1234:
 
  CPU 把它拆成:页号 = 1,页内偏移 = 0x234
 
  查页表:页号 1 对应物理页框 5
 
  物理地址 = 页框 5 的基地址 + 0x234
 
  程序根本不知道自己被映射到了页框 5。
 
  它只感觉"我读了 0x1234,拿到了数据"。
 

生活类比

 
大学宿舍楼:
 
  每间宿舍大小一样(每个格子 4KB)
 
  你宿舍在 302(虚拟地址)
 
  实际分给你的可能是 2 号楼 3 层 2 号房(物理地址)
 
  你写信给朋友说"我住 302"
 
  收发室(MMU)查表:302 → 2-3-2
 
  把信送过去
 
  你的朋友只知道你住 302,不知道你真实在哪。
 

分页的特点

维度说明
格子大小固定(通常 4KB)
有没有碎片内部碎片——程序最后一项不满 4KB,剩下空间浪费
保护每页可以设权限(读/写/执行)
目的解决内存碎片、支持虚拟内存、实现隔离

mindmap

  root((分页))

    物理内存切成等大的页框

    程序地址切成等大的页

    通过页表做映射

    优点:没外部碎片、方便虚拟内存

    缺点:有内部碎片、多一次查表

二、分页 vs 分段——核心区别

维度分页分段
切法固定大小(4KB)不固定(按逻辑)
谁决定大小硬件(CPU 架构决定)程序员/编译器
是否有碎片内部碎片(一个页没用满)外部碎片(段之间空隙)
权限控制每页设权限每段设权限
共享不方便(共享粒度太小)方便(整个代码段共享)
目的解决碎片、实现虚拟内存支持程序逻辑结构
程序能感知吗❌ 完全透明(不知道在哪一页)✅ 能感知
 
核心一句话:
 
  分页关注"内存怎么用得更高效"——解决碎片
 
  分段关注"程序结构怎么管理"——解决逻辑隔离
 

三、一张表横向对比

维度分页分段段页式
分割粒度固定(4KB)不固定分段后段内再分页
地址结构页号 + 偏移段号 + 偏移段号 + 页号 + 偏移
查表次数1 次(页表)1 次(段表)2 次(段表→页表)
是否有碎片内部碎片外部碎片内部碎片
权限控制每页每段每段 + 每页
程序感知不感知感知感知
复杂度
实际用在哪现代 OS 的主流早期 OS、嵌入式早期 x86

四、一句话讲清

Q:分页和分段的区别?

分页按固定大小切内存(4KB),目的是高效管理内存、消除外部碎片、支持虚拟内存。程序不感知分页。分段按程序逻辑切(代码段、数据段、栈段),目的是支持程序的逻辑结构和权限隔离。程序能感知段的存在。

Q:分页的碎片问题?

分页只有内部碎片——程序最后一页用不满 4KB,剩下的空间浪费。平均每个程序浪费半个页(约 2KB),但相比分段的外部碎片问题(段之间空出无法利用的空间)要轻得多。

Q:段页式是怎么工作的?

先按逻辑分段,每个段内部再分页。地址翻译分两步:先查段表找到段对应的页表,再查页表找到物理页框。比纯分页多查一次表,但兼具了分段和分页的优点。

Q:为什么现代操作系统不用段页式了?

主要是复杂度的代价不值得。现代操作系统用纯分页 + 虚拟内存就足够了,权限控制通过页表项里的权限位来实现,不需要分段。分段是 x86 架构早期留下来的遗产。

总结:分页管效率、分段管逻辑、段页式是组合。实际最爱考的是分页 vs 分段的区别——抓住”固定大小 vs 不固定”和”硬件决定 vs 逻辑决定”这两个维度就行。

速记卡(面试闪卡)

Q1:一句话讲清「分页 vs 分段 vs 段页式」到底是什么?

A:分页按固定格子切内存,分段按逻辑切块,段页式先分段再分页。

Q2:1. 分页 Paging —— 内存切成等格 —— 怎么理解?

A:分页像大学宿舍楼:每间一样大(4KB),你住 302(虚拟地址),收发室 MMU 查表把你映射到真实房间——你只感觉连续,其实散落各处。优点没外部碎片。英文 Paging / MMU。

Q3:2. 分段 Segmentation —— 按逻辑切块 —— 怎么理解?

A:分段像户型图:按代码段、数据段、栈段这种逻辑切,大小不一,程序能感知自己在哪段。好处是整个代码段好共享、权限好隔离,但段间会留外部碎片。英文 Segmentation。

Q4:3. 三者横向对比 —— 粒度与查表 —— 怎么理解?

A:分页固定 4KB、程序不感知、查一次页表、有内部碎片;分段不固定、程序感知、查段表、有外部碎片;段页式分段后段内再分页,地址=段号+页号+偏移,查两次表。英文 internal/external fragmentation。

Q5:4. 段页式为何被弃用 —— 怎么理解?

A:段页式先分段、段内再分页,兼得两者优点但多了一次查表、复杂度高。现代 OS 用纯分页+虚拟内存就够,权限靠页表位实现,分段只是 x86 早期遗产。英文 x86 legacy。

Q6:核心速记主线有哪些?

  • 分页:固定 4KB 格子,程序不感知,有内部碎片

  • 分段:按逻辑切块,程序感知,有外部碎片

  • 段页式:段内再分页,查两次表,现代已弃用

  • 关键区别:固定 vs 不固定、硬件决定 vs 逻辑决定

  • 页表:虚拟页号→物理页框的映射(MMU 查)

口诀

A:分页等格内存摊,

分段逻辑各分栏;

段页双表查两遍,

现代 OS 只用分页。

相关链接