Skip to content
标签
note
字数
1024 字
阅读时间
4 分钟

背景:从物理地址到虚拟地址

在没有操作系统的早期计算机(如单片机)中,程序直接操作的是内存的物理地址。这种方式简单直接,但存在严重问题:

  1. 地址空间不隔离:如果想同时运行两个程序,它们可能会读写同一块内存区域,导致数据错乱和程序崩溃。
  2. 内存使用效率低:程序必须加载到一块连续的、足够大的物理内存中才能运行。
  3. 程序编写困难:程序员需要自己管理内存地址,容易出错。

为了解决这些问题,现代操作系统引入了虚拟内存(Virtual Memory)机制。

操作系统为每个进程提供一个独立的、连续的、私有的虚拟地址空间(Virtual Address Space)。程序在运行时使用的是虚拟地址,而非真实的物理地址。

虚拟地址到物理地址的映射

当进程访问一个虚拟地址时,CPU 中的内存管理单元(MMU, Memory Management Unit) 会自动将这个虚拟地址翻译成对应的物理地址,然后再访问真实的物理内存。

虚拟内存的作用

  1. 隔离进程地址空间

    • 每个进程都有自己独立的虚拟地址空间和页表。一个进程无法访问另一个进程的内存,保证了进程的安全性。这也从根本上解决了多进程地址冲突的问题。
  2. 扩大可用内存空间

    • 虚拟内存使得进程可以使用的内存(虚拟内存)远大于物理内存的实际大小。操作系统利用程序的局部性原理(即程序在一段时间内只会访问一小部分数据),只将当前需要用到的数据和指令加载到物理内存中。
    • 不常用的数据可以被临时存放到硬盘的交换空间(Swap Space)中。当需要访问这些数据时,再通过缺页中断将其从硬盘换回物理内存。
  3. 提高内存使用效率和安全性

    • 内存共享:多个进程可以共享同一份物理内存,例如共享库(如 C 库),从而节省物理内存。
    • 权限控制:页表中的条目可以设置读、写、执行等权限位。这可以防止程序意外地修改只读数据(如代码段)或执行非代码数据,提高了系统的安全性。

虚拟内存的实现:段页式内存管理

现代操作系统普遍采用段页式内存管理来实现虚拟内存。

  • 分段(Segmentation):将程序的虚拟地址空间划分为若干个逻辑段(Segment),如代码段、数据段、堆栈段等。每个段有自己的大小和权限。
  • 分页(Paging):将虚拟地址空间和物理地址空间都划分为大小固定的页(Page)(如 4KB)。

段页式管理结合了两者的优点:

  1. 程序先按逻辑功能分段。
  2. 每个段再被划分为多个大小相等的页。
  3. 物理内存也被划分为同样大小的页框(Page Frame)
  4. 操作系统通过页表(Page Table)来记录虚拟页到物理页框的映射关系。

段页式内存管理

当 CPU 访问一个虚拟地址时,MMU 会:

  1. 通过段表找到对应的段。
  2. 在段内通过页表找到对应的物理页框。
  3. 结合页内偏移量,最终计算出物理地址。

贡献者

The avatar of contributor named as jiechen jiechen

页面历史

撰写