速通物理内存和虚拟内存
物理内存与虚拟内存
一、什么是物理内存?
物理内存(RAM)就是电脑里真实存在的内存空间。
电脑里有CPU , RAM(内存) , SSD(硬盘)
比如电脑安装了 16GB 内存条,就拥有约 16GB 的物理内存。
当我们运行一个 C 程序时,操作系统会把需要的程序内容加载到内存,再由 CPU 执行指令。
可以简单理解为:
- 硬盘:仓库,长期保存程序和文件。
- 内存:工作台,存放正在使用的数据。
- CPU:工人,负责执行指令和计算。
物理内存中的每个字节都有自己的地址,这个地址叫作物理地址。
二、什么是虚拟内存?
假设同时运行两个程序:
程序 A 想使用地址 1000,程序 B 也想使用地址 1000。
如果它们直接操作同一个物理位置,就可能互相覆盖数据。
为了解决内存管理和安全问题,现代操作系统引入了虚拟内存(Virtual Memory)。
虚拟内存是一种内存管理机制,让每个程序使用自己的虚拟地址空间。
举个宿舍的例子:
张三和李四的宿舍卡上都写着“101 号房间”。
但是学校实际安排的是:
| 学生 | 虚拟房间 | 真实房间 |
|---|---|---|
| 张三 | 101 | 305 |
| 李四 | 101 | 502 |
虽然两人的虚拟房间编号相同,但实际房间不同。
程序也是一样:
程序 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 环境下:
malloc()申请一段可以使用的虚拟地址空间。p[0] = 10真正访问内存。- 如果对应页面还没有物理映射,就可能触发缺页异常。
- 操作系统准备物理页面,更新页表。
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 中的内存大小 |
最后用一句话总结:
物理内存是真正存放数据的地方,虚拟内存让程序通过自己的虚拟地址使用内存,而操作系统和硬件负责管理两者之间的关系。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)