在 Linux 系统开发、运维以及底层性能调优的面试中,内存管理几乎是必考的核心模块。无论是排查 OOM、分析内存泄漏,还是理解 mmap、fork、零拷贝等机制,都离不开对虚拟内存、物理内存以及页表映射的深入理解。本文以面试问答的形式,系统梳理这三者之间的关系与工作流程。
一、为什么需要虚拟内存?
早期计算机直接访问物理内存,程序之间没有隔离,一个程序越界写入就可能破坏操作系统或其他进程的数据。虚拟内存的引入主要解决以下问题:
- 进程隔离:每个进程拥有独立的虚拟地址空间,无法直接触碰其他进程或内核的物理内存。
- 地址空间抽象:程序不再关心物理内存的实际布局,可以使用连续、统一的地址空间,即使物理内存是碎片化的。
- 内存超售:进程申请的虚拟内存总和可以超过实际物理内存,借助交换分区和按需调页机制运行。
- 共享与保护:多个进程可以映射同一份物理页(如共享库),同时通过页表权限位实现读、写、执行控制。
在 64 位 Linux 上,每个进程通常拥有 128TB 的用户空间虚拟地址范围(具体取决于架构和配置),而物理内存可能只有几十 GB,这中间的映射关系就是由页表来维护的。
二、虚拟内存与物理内存的关系
虚拟内存和物理内存之间并不是一一对应的,它们通过页表建立映射。几个关键点:
- 页(Page):虚拟内存和物理内存都被划分为固定大小的页,x86_64 默认页大小为 4KB,也支持 2MB 的大页和 1GB 的巨页。
- 页帧(Page Frame):物理内存被划分为页帧,每个页帧有一个物理页号(PFN)。
- 按需分配:进程调用 malloc 时,通常只是获得了虚拟地址范围的承诺,物理页帧在首次访问触发缺页异常时才真正分配。
- 写时复制(COW):fork 创建子进程时,父子进程共享同一物理页并标记为只读,任一进程写入时才复制出新页。
因此,一个进程的 VIRT(虚拟内存)远大于 RES(常驻物理内存)是正常现象,这并不代表内存泄漏。
三、页表映射是如何工作的
1. 多级页表结构
以 x86_64 的四级页表为例,虚拟地址被划分为多个索引字段:
- PGD(Page Global Directory)
- PUD(Page Upper Directory)
- PMD(Page Middle Directory)
- PTE(Page Table Entry)
- 页内偏移(12 位,对应 4KB 页)
CPU 中的 CR3 寄存器保存当前进程 PGD 的物理基地址。MMU 根据虚拟地址逐级查表,最终找到 PTE,从中取得物理页帧号,再加上页内偏移得到物理地址。
采用多级页表的好处是节省空间:对于未使用的虚拟地址区域,中间层级的页表项可以直接为空,不必分配完整的映射表。
2. TLB 加速
每次内存访问都走四级查表代价很高,因此 CPU 内置了 TLB(Translation Lookaside Buffer)缓存最近使用的虚拟页到物理页的映射。TLB 命中时无需查页表,直接完成地址转换;TLB 未命中时才触发硬件页表遍历。
进程切换时,如果使用不同的 PGD,需要刷新 TLB(或使用 PCID 标记避免全量刷新),这也是上下文切换开销的一部分。
3. 缺页异常处理
当 MMU 查表发现 PTE 为空或权限不匹配时,会触发缺页异常,进入内核的 do_page_fault 流程:
- 合法但未分配:如首次访问 malloc 得到的地址,内核分配物理页帧、填写 PTE,然后返回用户态重新执行指令。
- 页在交换分区:从 swap 读回页面,更新 PTE。
- 写时复制:为当前进程复制一份新的物理页,改为可写。
- 非法访问:地址不属于进程的合法 VMA,内核发送 SIGSEGV 终止进程。
四、常见面试追问
问:虚拟内存比物理内存大很多,会不会有问题?
答:不会直接出问题,但物理内存不足时会触发页回收或 swap,若回收跟不上分配速度,就会触发 OOM Killer。关键在于工作集(实际频繁访问的页)是否超过物理内存。
问:malloc 分配的内存立刻占用物理内存吗?
答:不一定。小分配走 brk,大分配走 mmap,通常都是惰性分配。只有真正写入时才通过缺页异常分配物理页。
问:为什么页表本身也占用内存?
答:每个进程都需要一套页表,映射越多,页表层级越深,占用的物理内存越多。大量进程或大量 mmap 区域会导致页表内存开销显著上升,可通过 /proc/meminfo 中的 PageTables 观察。
问:大页(HugePage)有什么优势?
答:减少页表层级和 TLB 条目数量,降低 TLB miss,提升大内存应用的性能,常用于数据库和虚拟化场景。
五、总结
虚拟内存为每个进程提供独立、连续、可保护的地址空间;物理内存是实际存储数据的页帧集合;页表则是连接两者的桥梁,由 MMU 硬件配合内核软件共同维护。理解按需调页、写时复制、缺页异常和 TLB 机制,不仅能应对面试,更是排查内存问题、进行系统调优的基础。建议结合 /proc/[pid]/maps、/proc/[pid]/smaps 以及 perf、vmstat 等工具实际观察,加深理解。
未经允许不得转载:任鹏个人博客 » Linux 面试题:虚拟内存、物理内存与页表映射是如何工作的

