Skip to content

地址空间

一、 早期系统与内存使用

  1. 早期系统内存模型:

    • 操作系统占据物理内存的一部分 (如从地址0开始)。

    • 运行的单个用户程序占据剩余物理内存 (如从64KB开始)。

    • 抽象极少: 用户程序直接操作物理地址。

    • 期望不高: 功能简单,开发者生活“轻松”。

二、 多道程序与时分共享的演进

  1. 多道程序 (Multiprogramming):

    • 动机: 提高昂贵机器的CPU利用率。

    • 实现: 多个进程准备运行,当一个进程等待I/O时,操作系统切换到另一个进程。

    • 效率提升: 减少CPU空闲时间。

  2. 时分共享 (Time Sharing):

    • 动机: 满足用户对交互性的需求,允许多个用户同时使用机器并获得及时响应。

    • 早期粗糙实现:

      • 一个进程独占内存运行一小段时间。

      • 将其所有状态 (包括全部物理内存) 保存到磁盘。

      • 加载另一个进程的状态运行。

      • 问题: 速度太慢,尤其当内存增大时。

    • 改进实现 :

      • 多个进程(A、B、C)同时驻留在物理内存中,每个进程分配一小部分内存。

      • 操作系统选择一个运行,其余等待。

      • 新需求: 保护 (Protection)。防止进程间相互干扰内存。

三、 地址空间 (Address Space)

  1. 定义: 操作系统为运行程序提供的物理内存的抽象。是程序看到的内存视图。

  2. 核心作用: 理解内存虚拟化的关键。

  3. 地址空间的内容:

    • 代码 (Code): 程序的指令,通常静态,位于地址空间特定区域 (如顶部)。

    • 栈 (Stack):

      • 保存当前函数调用信息、局部变量、参数、返回值。

      • 通常从地址空间的一端开始,向特定方向增长 (如从底部向上增长)。

    • 堆 (Heap):

      • 用于动态分配、用户管理的内存 (如 malloc() 或 new)。

      • 通常位于代码区之后,向与栈相反的方向增长 (如从代码区向下增长)。

    • 其他: 静态初始化变量等。

  4. 地址空间的特性 :

    • 是一个逻辑概念,程序认为自己拥有从0开始的一块连续内存。

    • 栈和堆通常放置在两端,以便它们可以独立增长。

    • 这种布局只是一种约定,多线程环境下可能不同。

四、 关键问题:如何虚拟化内存?

  • 挑战: 操作系统如何在单一物理内存上,为多个共享内存的进程构建一个私有的、可能很大的地址空间的抽象?

  • 虚拟化内存 (Virtualizing Memory):

    • 程序以为自己加载到特定虚拟地址 (如0)。

    • 操作系统和硬件配合,将虚拟地址转换为实际的物理地址。

    • 例如:进程A尝试访问虚拟地址0,实际访问的是物理地址320KB。

五、 虚拟内存的目标

  1. 透明性 (Transparency):

    • 运行程序不应感知到内存被虚拟化。

    • 程序行为如同拥有私有物理内存。

    • 操作系统和硬件在幕后完成复用和隔离。

  2. 效率 (Efficiency):

    • 虚拟化应尽可能高效 (时间和空间)。

    • 依赖硬件支持 (如 TLB)。

  3. 保护 (Protection):

    • 进程间互相保护,操作系统也受保护。

    • 进程不能访问其地址空间之外的内存。

    • 实现进程间的隔离 (Isolation)

六、 补充:你看到的所有地址都不是真的

  • C程序中打印出的指针地址、函数地址、栈变量地址等都是虚拟地址

  • 只有操作系统和硬件知道这些虚拟地址对应的物理地址