物理内存与虚拟内存

一、什么是物理内存?

物理内存(RAM)就是电脑里真实存在的内存空间。

电脑里有CPU , RAM(内存) , SSD(硬盘)

比如电脑安装了 16GB 内存条,就拥有约 16GB 的物理内存。

当我们运行一个 C 程序时,操作系统会把需要的程序内容加载到内存,再由 CPU 执行指令。

可以简单理解为:

  • 硬盘:仓库,长期保存程序和文件。
  • 内存:工作台,存放正在使用的数据。
  • CPU:工人,负责执行指令和计算。

物理内存中的每个字节都有自己的地址,这个地址叫作物理地址。

二、什么是虚拟内存?

假设同时运行两个程序:

程序 A 想使用地址 1000,程序 B 也想使用地址 1000。

如果它们直接操作同一个物理位置,就可能互相覆盖数据。

为了解决内存管理和安全问题,现代操作系统引入了虚拟内存(Virtual Memory)。

虚拟内存是一种内存管理机制,让每个程序使用自己的虚拟地址空间。

举个宿舍的例子:

张三和李四的宿舍卡上都写着“101 号房间”。

但是学校实际安排的是:

学生虚拟房间真实房间
张三101305
李四101502

虽然两人的虚拟房间编号相同,但实际房间不同。

程序也是一样:

程序 A:虚拟地址 1000 → 物理地址 3000
程序 B:虚拟地址 1000 → 物理地址 5000

因此,两个程序即使使用相同的虚拟地址,也可以访问不同的物理内存。

虚拟内存的主要好处是:隔离程序、保护内存、方便操作系统管理。

另外,虚拟内存还能让程序不必关心数据实际存放在物理内存的哪个位置。

三、虚拟地址如何找到物理地址?

这里需要认识三个概念:页、页表、MMU。

1. 页(Page)

为了方便管理,计算机会把虚拟地址空间分成一块一块的,每一块叫作一个页。

物理内存也分成相同大小的块,叫作页框。

很多 Linux 系统使用 4KiB(4096 字节)大小的页面。

1KiB = 1024字节

1MiB = 1024KiB

1GiB = 1024MiB

1TiB = 1024GiB

注意MB与GB之类的转化单位是1000
而MiB与GiB之类的转化单位是1024

2. 页表(Page Table)

页表负责记录虚拟页和物理页框的对应关系。

就像宿舍登记册:

虚拟页物理页框
第 0 页第 3 块
第 1 页第 5 块
第 2 页第 7 块

例如:

程序访问虚拟第 1 页中的第 100 个字节。

查询映射后,就会访问物理第 5 块中的第 100 个字节。

页号可以改变,但页内位置不变。

3. MMU 和 TLB

MMU(内存管理单元) 是负责地址转换的硬件。

TLB 则是缓存常用地址转换结果的高速缓存。

可以这样理解:

  • 页表:完整的宿舍登记册。
  • MMU:负责查找的管理员。
  • TLB:管理员记录常用信息的小纸条。

地址转换过程:

CPU 发出虚拟地址
        ↓
MMU 查询 TLB
        ↓
找到了 → 使用缓存的映射
没找到 → 查询页表
        ↓
获得有效物理地址
        ↓
访问物理内存

如果 TLB 已经找到了有效映射,就不需要再查询页表。

四、什么是缺页异常?

假设学生拿着宿舍卡找管理员,却发现自己的房间还没安排好。

管理员需要先检查他有没有使用权限,再决定是否安排房间。

计算机也有类似的情况。

缺页异常(Page Fault)就是 CPU 发现当前页面映射无法满足访问,需要操作系统处理。

如果访问合法,操作系统可以分配物理页面、更新页表,让程序继续运行。

例如,我们使用 malloc() 申请一块内存。

在常见的 Linux 环境下,申请成功后,不一定立刻分配等量的物理内存。

假设 p 是申请成功后得到的指针,这时执行:

p[0] = 10;

如果对应页面还没有物理映射,就可能触发缺页异常。操作系统会检查访问是否合法,并在需要时分配物理页面。

如果访问不合法,程序可能出现:

Segmentation fault

也就是段错误。

所以要记住:

缺页异常不一定是错误,合法的缺页异常可以被正常处理。

五、什么是 Swap?

假设学校宿舍住满了,但又来了新同学。

管理员可以把某个暂时不用的房间里的东西搬到仓库,腾出房间给新同学。

这就类似 Linux 的 Swap(交换空间)。

当物理内存紧张时,Linux 可以把部分暂时不用的内存页面转移到 Swap 中。

  • RAM:真实宿舍,访问速度快。
  • Swap:临时仓库,通常位于硬盘上,访问速度较慢。

如果频繁使用 Swap 进行页面交换,电脑就可能变卡。

注意:

8GB RAM + 8GB Swap,不等于 16GB 物理内存。

而且:

虚拟内存不等于 Swap。即使没有 Swap,Linux 也能使用虚拟内存。

六、结合 C 语言理解虚拟内存

我们来看一段代码:

#include <stdlib.h>

int main(void)
{
    char *p = malloc(4096);

    if (p == NULL)
        return 1;

    p[0] = 10;

    free(p);

    return 0;
}

在常见的 Linux 环境下:

  1. malloc() 申请一段可以使用的虚拟地址空间。
  2. p[0] = 10 真正访问内存。
  3. 如果对应页面还没有物理映射,就可能触发缺页异常。
  4. 操作系统准备物理页面,更新页表。
  5. free() 释放申请的内存,供后续复用。

重点:malloc 成功,并不代表立刻占用了同等大小的物理 RAM。

七、Ubuntu 实际操作

1. 查看物理内存与 Swap

打开终端:

free -h

其中:

  • free:查看系统内存使用情况。
  • -h:以容易阅读的单位显示。

重点关注:

Mem:物理内存。

Swap:交换空间。

2. 查看程序的虚拟内存和物理内存

假设正在运行一个名叫 vm_demo 的程序:

ps -C vm_demo -o pid,vsz,rss,comm

其中:

字段含义
PID进程编号
VSZ虚拟地址空间大小
RSS进程当前驻留在物理内存中的页面总量,可能包含共享内存
COMM进程名称

VSZ 和 RSS 在这里通常以 KiB 为单位。

例如,一个程序显示:

VSZ = 10485760 KiB
RSS = 2097152 KiB

也就是:

虚拟地址空间约 10GiB,驻留物理内存约 2GiB。

即使电脑只有 8GiB RAM,也不矛盾。

因为虚拟地址空间大小不等于实际占用的物理内存大小。

另外,RSS 可能包含共享页面,并不全部代表进程独占的物理内存。


八、总结

知识点简单理解
物理内存真实存在的 RAM
虚拟内存管理程序地址空间的机制
页虚拟地址空间中的一块
页表记录虚拟页与物理页框的映射
MMU负责地址转换
TLB缓存常用地址转换结果
缺页异常页面暂时无法正常访问,需要操作系统处理
Swap临时保存部分换出页面的空间
VSZ进程虚拟地址空间大小
RSS进程当前驻留在 RAM 中的内存大小

最后用一句话总结:

物理内存是真正存放数据的地方,虚拟内存让程序通过自己的虚拟地址使用内存,而操作系统和硬件负责管理两者之间的关系。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐