虚拟内存vm

虚拟内存

一、 虚拟内存 (VM) 概述

  1. 核心思想: 为每个进程提供一个私有的、连续的、巨大的地址空间,称为虚拟地址空间 (Virtual Address Space),它与物理内存(DRAM)的大小和组织方式解耦。

  2. 关键特性:

    • 抽象 (Abstraction): 提供了一个比物理内存更易于使用的内存模型。
    • 透明 (Transparent): 用户程序通常感知不到虚拟内存的存在,像直接操作真实内存一样。
    • 高效 (Efficient): 性能是 VM 机制被广泛接受的前提。
    • 保护/隔离 (Protection / Isolation): 进程的虚拟地址空间是私有的,不能访问其他进程或内核的地址空间,提供了内存保护。
  3. 地址类型:

    • 虚拟地址 (Virtual Address, VA): CPU 生成的、程序使用的地址。
    • 物理地址 (Physical Address, PA): 硬件内存(DRAM)中的实际地址。
  4. 地址翻译 (Address Translation):

    • 定义:虚拟地址 (VA) 转换为物理地址 (PA) 的过程。

    • **机制:**需要硬件 (HW)和操作系统 (OS)紧密协作。

      • 硬件: 内存管理单元 (Memory Management Unit, MMU),CPU 芯片上的专用硬件,负责动态、快速地翻译地址。
      • 软件 (OS): 维护页表 (Page Table) 等查找结构(存储在主存中,MMU 可以访问),记录 VA 到 PA 的映射关系。

二、 物理寻址 vs. 虚拟寻址

  1. 物理寻址 (Physical Addressing):
    • CPU 直接使用物理地址 (PA) 访问主存。
    • 主存被看作一个连续的字节数组,每个字节有唯一 PA。
    • 应用于早期 PC、嵌入式系统、某些超级计算机等相对简单的系统。
  2. 虚拟寻址 (Virtual Addressing):
    • CPU 生成虚拟地址 (VA)
    • VA 必须先通过 MMU 和页表翻译成 PA,然后才能访问主存。
    • 应用于所有现代服务器、桌面和笔记本电脑。是计算机科学中的伟大思想之一。

三、 地址空间 (Address Space)

  1. 虚拟地址空间 (Virtual Address Space):
    • 大小由地址总线位数 n 决定,包含 N = 2 n N=2^n N=2n 个虚拟地址,范围从 0 N − 1 N−1 N1
    • 每个进程拥有独立的虚拟地址空间。
  2. 物理地址空间 (Physical Address Space):
    • 大小由物理内存容量决定,设地址线有 m 位,则包含 M = 2 m M=2^m M=2m 个物理地址,范围从 0 M − 1 M−1 M1
    • 所有进程共享物理地址空间。
  3. 多对一映射: 同一个物理内存单元可以被不同进程的不同虚拟地址映射(用于共享),或者在不同时间被同一进程的不同虚拟地址映射。

四、 用户视角:内存 API (Memory API)

  • 栈 (Stack): 用于存储局部变量、函数参数、返回地址等。通常由编译器自动管理,向下增长。

  • 堆 (Heap): 用于动态内存分配。由程序员通过库函数管理,向上增长。

    • malloc(): 分配指定大小的未初始化内存。
    • free(): 释放之前 malloc 分配的内存。
    • calloc(): 分配内存并初始化为 0。
    • realloc(): 调整已分配内存的大小(可能涉及数据拷贝)。
  • malloc/free 与系统调用:

    • mallocfree 是 C 库函数,不是系统调用
    • 库函数内部维护数据结构来管理可用内存块。
    • 当库函数发现现有空闲空间不足以满足 malloc 请求时,会调用 brkmmap 系统调用向操作系统申请更多内存(扩大堆区域)。
    • free 通常只是将内存标记为可用,并放回库函数的内部空闲列表,不一定立即归还给操作系统
  • brk 系统调用: 用于改变堆顶指针 (program break) 的位置,从而扩大或缩小堆区。一般由内存分配库函数调用,不建议用户程序直接调用。

五、 虚拟内存的核心动机 (Why VM?)

  1. 高效利用 DRAM (VM as a Cache):
    • 将 DRAM 视为磁盘上更大虚拟地址空间的一个缓存 (Cache)
    • 只将程序当前需要的活动部分保留在 DRAM 中,其余部分放在磁盘上。
    • 克服物理内存大小的限制,支持运行比物理内存更大的程序。
  2. 简化内存管理 (VM as a Management Tool):
    • 统一的地址空间: 每个进程都看到一个相同的、线性的、从 0 开始的虚拟地址空间布局(代码段、数据段、堆、共享库、栈等总在相似的虚拟地址范围)。这极大地简化了链接 (Linking)加载 (Loading) 过程。
    • 简化内存分配: OS 为进程分配物理内存页,并将它们映射到进程的虚拟地址空间。虚拟地址空间中连续的页面在物理内存中不必连续,便于 OS 寻找空闲物理页。
    • 简化共享: 通过让不同进程的虚拟页面映射到同一个物理页面,可以轻松实现代码(如共享库)和数据(如 IPC 机制)的共享。
  3. 提供内存保护 (VM as a Protection Tool):
    • 地址空间隔离: 每个进程的页表是独立的,确保一个进程不能访问其他进程的物理内存。
    • 权限控制: 页表项 (PTE) 中可以包含权限位 (如读 READ, 写 WRITE, 执行 EXECUTE, 内核态访问 SUPERVISOR)。
    • 硬件检查: MMU 在每次地址翻译时都会检查访问权限。
    • 违例处理: 如果发生权限冲突(如用户态代码试图写入只读页面,或访问内核空间),MMU 会触发保护故障 (Protection Fault) (一种页错误),内核的故障处理程序会检查原因,若确实违规,则向进程发送 SIGSEGV (Segmentation Fault) 信号,通常导致进程终止。

六、 VM 作为 DRAM 缓存的机制

  1. 分页 (Paging):
    • 虚拟内存和物理内存都被划分为固定大小的块,称为页 (Page)
    • 虚拟内存中的页称为虚拟页 (Virtual Page, VP)
    • 物理内存中的页称为物理页 (Physical Page, PP)页帧 (Page Frame)
    • 页是数据传输的基本单位(在磁盘和内存之间,或内存和缓存之间)。页大小通常是 4KB 到 2MB。
  2. 页表 (Page Table):
    • 每个进程一个页表,存储在内核管理的内存中。
    • 是一个页表条目 (Page Table Entry, PTE) 的数组。
    • 映射: 页表建立了虚拟页号 (VPN)物理页号 (PPN) 或磁盘地址的映射。
    • PTE 结构 (简化):
      • 有效位 (Valid Bit): 指示该虚拟页当前是否缓存在物理内存 (DRAM) 中。1 表示有效(在内存中),0 表示无效(不在内存中,可能在磁盘上或未分配)。
      • 物理页号 (PPN): 如果有效位为 1,这里存储对应的物理页号。
      • 磁盘地址: 如果有效位为 0 且页面已被分配并换出,这里可能存储页面在磁盘上的位置信息。
      • 权限位: R, W, X, S 等。
  3. 页面状态 (Page States):
    • 未分配 (Unallocated): VM 系统尚未创建或分配的 VP,不占用磁盘或内存空间,对应 PTE 通常为 null 或标记为无效。
    • 未缓存 (Uncached): 已分配的 VP,但当前不在物理内存中,其内容在磁盘上,对应 PTE 的有效位为 0。
    • 已缓存 (Cached): 已分配的 VP,当前在物理内存中,对应 PTE 的有效位为 1,并包含有效的 PPN。
  4. 页命中 (Page Hit):
    • CPU 访问一个 VA,对应的 VP 恰好在物理内存中 (PTE 有效位为 1)。
    • MMU 利用 PTE 中的 PPN 和 VA 中的页内偏移量计算出 PA,访问物理内存。
  5. 缺页故障 (Page Fault / Page Miss):
    • CPU 访问一个 VA,对应的 VP 不在物理内存中 (PTE 有效位为 0)。
    • MMU 无法完成地址翻译,触发一个异常 (Exception),称为缺页故障,将控制权转移给内核的缺页处理程序。
    • 处理流程:
      1. 选择牺牲页 (Victim Page): 如果物理内存已满,内核需要选择一个当前在内存中的物理页作为牺牲品(基于某种页面替换算法,如 LRU)。
      2. 写回 (Write Back): 如果牺牲页被修改过(“脏页”),需要先将其内容写回到磁盘。
      3. 加载 (Load): 内核从磁盘读取所需的虚拟页内容到被选中的物理页帧中。
      4. 更新页表: 修改磁盘换入页的 PTE(设置有效位为 1,填入 PPN)和(如果发生替换)牺牲页的 PTE(设置有效位为 0)。
      5. 重启指令: 内核处理完成后,返回到用户进程,重新执行导致缺页的指令。此时,由于页面已在内存中,会发生页命中。
  6. 分配新页 (Allocating Pages):
    • 当进程需要新的内存页时(如 malloc 首次访问新申请的堆空间),OS 需要在虚拟地址空间中分配 VP,可能需要在磁盘上为其预留空间,并更新页表(初始时标记为未缓存,有效位为 0)。首次访问该 VP 会触发缺页故障,将其加载到内存。
  7. 局部性原理 (Locality):
    • 虚拟内存之所以高效,是因为程序通常表现出时间局部性(刚访问过的内存很可能再次访问)和空间局部性(访问某内存位置后很可能访问其附近位置)。
    • 这使得程序在任何时刻实际需要的活动页面集合(工作集, Working Set)通常远小于其总的虚拟地址空间,并且常常能装入物理内存。
    • 颠簸 (Thrashing): 如果系统中所有进程的工作集之和远大于物理内存,会导致页面频繁地换入换出,系统大部分时间在进行磁盘 I/O 而不是计算,性能急剧下降。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橙汁味的风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值