2. 页面大小基础
2.1 标准4KB页面与Linux内存分页机制
Linux内核将物理内存划分为固定大小的块,称为页面(Page)。标准页面大小为 4KB(x86_64 / ARM64 架构)。这是内存管理的最小粒度,也是页表(Page Table)和TLB(Translation Lookaside Buffer)工作的基本单元。
当进程访问虚拟地址时,MMU(内存管理单元)将虚拟地址拆分为页号(VPN)和页内偏移(Offset)。页号通过页表转换为物理页号(PPN),再与偏移拼接得到物理地址。这个过程称为地址翻译。
关键指标:4KB页面下,虚拟地址的低12位为页内偏移(212 = 4096 = 4KB),高位为页号。
为什么是4KB? 4KB是历史与性能的折中:过小会导致页表膨胀、TLB覆盖范围小;过大会造成内部碎片(Internal Fragmentation)。Linux默认选择4KB作为标准页面大小。
2.2 页面大小与页表层级深度(4级/5级页表)
为了支持庞大的虚拟地址空间(x86_64为48位,5级页表支持57位),Linux采用多级页表结构。页面大小直接影响页表的层级深度和内存占用。
以x86_64 4级页表为例,虚拟地址被划分为5个部分:
- PML4(Page Map Level 4):9位索引,指向下一级页表
- PUD(Page Upper Directory):9位索引
- PMD(Page Middle Directory):9位索引
- PTE(Page Table Entry):9位索引,指向物理页
- Offset:12位(4KB页面)
当页面大小增大时,页内偏移位数增加,页表层级深度可能减少。例如,使用2MB大页时,Offset为21位,PMD级页表直接指向物理页,省去了PTE层级,变为3级页表。
| 页面大小 | 偏移位数 | 页表层级(x86_64) | 页表项数量(覆盖相同内存) |
|---|---|---|---|
| 4KB | 12 | 4级(PML4→PUD→PMD→PTE) | 多(每4KB一项) |
| 2MB | 21 | 3级(PML4→PUD→PMD) | 少(每2MB一项) |
| 1GB | 30 | 2级(PML4→PUD) | 极少(每1GB一项) |
注意:5级页表(5-level paging)在x86_64上支持57位虚拟地址,增加了一层PML5。此时4KB页面需要5级翻译,而2MB大页仍可减少一级。层级越深,TLB miss时的页表遍历开销越大。
2.3 页面大小对TLB覆盖范围的影响
TLB是MMU内部的高速缓存,用于缓存最近使用的虚拟地址到物理地址的映射。TLB的覆盖范围(Coverage)定义为:
TLB覆盖范围 = TLB条目数 × 页面大小
在TLB条目数固定的情况下,页面大小越大,TLB能覆盖的内存范围越大。例如:
- 4KB页面:64个TLB条目覆盖 64 × 4KB = 256KB
- 2MB大页:64个TLB条目覆盖 64 × 2MB = 128MB
- 1GB大页:64个TLB条目覆盖 64 × 1GB = 64GB
核心结论:使用大页可以显著扩大TLB覆盖范围,减少TLB miss次数,提升内存密集型应用的性能。但大页也会带来内部碎片和分配灵活性下降的问题。
2.4 页面大小选择的权衡
| 页面大小 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| 4KB | 内部碎片小,内存利用率高;分配灵活 | TLB覆盖范围小;页表层级深,遍历开销大 | 通用场景、小内存进程、碎片敏感型应用 |
| 2MB | TLB覆盖范围大;页表层级减少;TLB miss降低 | 内部碎片可能增加;需要连续物理内存 | 数据库、HPC、内存密集型服务、虚拟化 |
| 1GB | TLB覆盖范围极大;页表层级最少 | 内部碎片严重;分配困难;需要硬件支持 | 大型数据库、科学计算、GPU显存映射 |
实践建议:对于大多数Linux服务器工作负载,启用透明大页(Transparent HugePages, THP)可以在不修改应用的情况下自动使用2MB大页,是平衡性能与兼容性的首选方案。对于延迟敏感型应用,建议手动管理大页(HugeTLB)以避免THP带来的额外开销。
2.5 本章小结
- 标准4KB页面是Linux内存管理的基础,但TLB覆盖范围有限。
- 页面大小直接影响页表层级深度:大页减少页表层级,降低地址翻译开销。
- TLB覆盖范围 = TLB条目数 × 页面大小,大页可显著扩大覆盖范围。
- 页面大小选择需要在TLB性能与内存碎片之间权衡,不同场景适用不同策略。