← 返回所有文章

SYSTEMS / 002//4 分钟阅读

虚拟内存:为什么每个程序都像拥有整台机器

理解地址空间、分页、缺页与缓存,建立一张清晰的内存地图。

程序里打印出的指针,通常是虚拟地址。它不是内存条上的直接坐标,而是进程所看到的地址空间中的一个位置。

地址空间是一层抽象

两个不同进程可以使用数值相同的虚拟地址,却映射到不同的物理内存。操作系统与硬件配合完成地址转换,进程通常不需要关心具体使用了哪块内存条。

这层抽象同时服务于隔离、共享和灵活分配。内核可以限制哪些区域可读、可写、可执行,也可以把同一个物理页映射到多个进程。

进程 A:虚拟页 0x10 ───→ 物理页 0x83
进程 B:虚拟页 0x10 ───→ 物理页 0x2A

相同的虚拟地址 ≠ 相同的物理位置

为什么要分页

分页把内存划分为固定大小的单位。页表记录虚拟页与物理页之间的映射以及访问权限。常见页大小是 4 KiB,但具体系统还可能支持其他大小和大页。

每次访存都查完整页表会增加开销,因此处理器使用 TLB 缓存部分地址转换结果。这里要区分:TLB 缓存的是地址转换信息,CPU 数据缓存主要缓存的是内存内容。

缺页不是程序一定出错

当访问的虚拟页尚未建立可用映射,或者不符合访问权限时,处理器会触发相应异常,交给内核处理。内核可能分配新页、载入文件内容或执行写时复制;非法访问则可能导致进程收到信号并终止。

因此,缺页并不都意味着从交换分区读取数据。轻微缺页与需要 I/O 的严重缺页,代价也可能相差很大。

看内存时,不只看一个数字

# 概览内存,重点结合 available 理解
free -h

# 查看进程内存映射,1234 替换为实际 PID
pmap -x 1234

# 查看虚拟内存与换页活动,第一行通常是启动以来的平均值
vmstat 1 5

虚拟内存大小大,不代表占用了同样多的物理内存。RSS 反映驻留的物理页,但共享页可能同时计入多个进程的 RSS,简单求和会重复计算。

Linux 还会把空闲内存用于文件缓存,这些缓存的一部分可以在需要时回收。「free 很少」不能单独作为内存不足的判断。

一个实用的性能直觉

访问连续数据,通常比随机跳转更容易利用缓存。写程序时可以先考虑数据布局与访问模式,再考虑微小的语法优化。

虚拟内存让程序拥有一致的地址视图;真正的性能仍然由映射、工作集大小、局部性和实际 I/O 共同决定。

继续阅读

EOF / 感谢阅读继续探索 ↗

搜索笔记

在全部文章中搜索