•Operating System
虚拟地址物理地址
**物理地址**是内存条上真实存在的地址,CPU 通过它直接访问内存芯片上的某个位置,硬件层面定死在那了。
Operating System
物理地址是内存条上真实存在的地址,CPU 通过它直接访问内存芯片上的某个位置,硬件层面定死在那了。
逻辑地址是程序运行时看到的地址,由 CPU 生成,程序员写代码、编译器分配变量用的都是它。操作系统通过页表把逻辑地址映射到物理地址,程序压根不知道数据实际存哪儿。
每个进程都有自己独立的逻辑地址空间,进程 A 的 0x1000 和进程 B 的 0x1000 可以指向完全不同的物理内存,这样就实现了进程间的内存隔离,一个进程崩了不会把别的进程带走。
地址转换流程是这样的:
- 程序访问逻辑地址 0x000A1234,逻辑地址由两部分组成分别是页号和页内偏移
- CPU 把这个地址交给 MMU内存管理单元
- MMU 拿到页号去查页表,找到对应的物理页框号,最后拼上页内偏移得到物理地址 0x1F2B5678
- 然后才真正去内存条上读数据。
为什么要搞两套地址
早期计算机程序直接操作物理地址,带来一堆麻烦事。程序必须知道自己被加载到内存的哪个位置,不同程序不能占用相同地址,一个程序写错地址可能直接把操作系统内存给覆盖了,整个系统就崩了。
引入逻辑地址后,每个程序都以为自己独占了整个内存空间,从 0 地址开始往上用,爱怎么访问怎么访问。
操作系统在背后默默做地址转换,把各个程序的逻辑地址映射到物理内存的不同区域,互不干扰。
地址转换的核心组件
MMU 是地址转换的硬件核心,集成在 CPU 里面。它接收 CPU 发出的逻辑地址,查页表做转换,输出物理地址。
这个过程对程序完全透明,程序以为自己在访问 0x1000,实际上 MMU 已经悄悄换成了 0x7F001000。
页表是操作系统维护的数据结构,记录逻辑页号到物理页框号的映射。
每个进程有自己的页表,进程切换的时候操作系统会把新进程的页表基地址写入 CPU 的 CR3 寄存器,MMU 就知道去哪儿查表了。
分段和分页
分段和分页器其实就是操作系统管理内存的不同方式。
- 分页:强调固定大小块,解决内存分配不连续的问题。
- 分段:强调逻辑结构,方便程序保护和共享。
分页(Paging)
核心概念:
- 把 物理内存 和 虚拟内存都划分成固定大小的块。
- 虚拟内存的块叫 页(Page),物理内存的块叫 页框(Frame)。
- 页和页框大小相同(常见 4KB、8KB 等)。
工作原理:
- CPU 生成虚拟地址 → 通过 页表 映射到物理地址。
- 页表存储每个虚拟页对应的物理页框地址。
- 程序只看到连续的虚拟地址,实际物理内存可能不连续。
优点:
- 不存在外部碎片(因为页固定大小)。
- 支持虚拟内存交换(Swap),可以把页临时换到磁盘。
缺点:
- 可能有少量内部碎片(页最后部分未用完)。
- 页表占用额外内存,页表过大时需要多级页表或 TLB。
分段(Segmentation)
核心概念:
- 按 逻辑结构 把程序划分成若干段。
- 常见段:代码段(text)、数据段(data)、栈段(stack) 等。
- 段大小不固定。
工作原理:
- 每个段有 段号 和 段内偏移(Segment:Offset)。
- CPU 使用 段表 → 找到段的起始物理地址,然后加偏移得到物理地址。
优点:
- 与程序逻辑更接近,便于保护和共享。
- 外部碎片较小,只要段连续即可。
缺点:
- 段大小不固定,容易产生 外部碎片。
- 管理复杂,需要段表和段长度检查。
| 特性 | 分页(Paging) | 分段(Segmentation) |
|---|---|---|
| 划分依据 | 固定大小块(页) | 程序逻辑结构(段) |
| 块大小 | 固定 | 不固定 |
| 内存连续性 | 物理内存可不连续 | 每段物理内存必须连续 |
| 碎片情况 | 内部碎片可能 | 外部碎片可能 |
| 映射方式 | 页表 | 段表 + 段内偏移 |
| 优点 | 简单、易管理、支持虚拟内存交换 | 贴近程序逻辑、便于共享和保护 |
| 缺点 | 需要额外页表,内部碎片 | 外部碎片,管理复杂 |