内存
→ 返回计算机基础
存储层次
寄存器 ~0.3 ns 字节级 CPU 内部
L1 Cache ~1 ns KB 级 CPU 内,每核独有
L2 Cache ~4 ns MB 级 CPU 内,每核独有
L3 Cache ~15 ns MB~GB 级 CPU 内,多核共享
内存(DRAM) ~60 ns GB 级 主板插槽
SSD ~100 μs TB 级 持久化
HDD ~10 ms TB 级 持久化
越靠近 CPU 越快越贵,容量越小。
DRAM 原理
DRAM(Dynamic RAM):用电容存储 1 位数据,电容会漏电,需要周期性刷新(refresh)。
1 bit = 1 个晶体管 + 1 个电容
- 优点:集成度高,单位容量成本低
- 缺点:速度慢,需要刷新
SRAM(Static RAM):用触发器存储,不需刷新,速度快,用于 Cache;但面积大、功耗高、成本高。
内存条规格
| 代数 | 标准 | 典型频率 | 带宽(单条) |
|---|---|---|---|
| DDR3 | PC3 | 1333~2133 MHz | 10~17 GB/s |
| DDR4 | PC4 | 2133~3600 MHz | 17~29 GB/s |
| DDR5 | PC5 | 4800~8000 MHz | 38~64 GB/s |
双通道:两条内存同时工作,理论带宽翻倍。
物理地址与虚拟地址
程序使用虚拟地址,CPU 通过 MMU(内存管理单元)将虚拟地址转换为物理地址。
虚拟地址 → MMU(页表查询)→ 物理地址 → DRAM
好处:
- 每个进程有独立地址空间,互不干扰
- 支持内存比物理内存大(虚拟内存 / 换页)
- 权限控制(只读、不可执行等)
分页(Paging)
内存被划分为固定大小的页(Page),典型大小 4 KB。
虚拟地址 = 虚拟页号(VPN)+ 页内偏移(Offset)
物理地址 = 物理页号(PPN)+ 页内偏移
页表:存储 VPN → PPN 的映射,每个进程一份,存放在内存中。
TLB(Translation Lookaside Buffer):页表的 Cache,存放最近使用的 VPN→PPN 映射,命中时无需访问内存中的页表。
多级页表(x86-64 用 4 级):避免页表本身占用太多内存,只分配实际使用的部分。
缺页中断(Page Fault)
访问的虚拟页不在物理内存中时触发:
1. CPU 触发缺页中断
2. OS 找到空闲物理页(不够则换出脏页到磁盘)
3. 从磁盘加载数据到物理页
4. 更新页表
5. 重新执行出错指令
内存碎片
| 类型 | 说明 | 解决 |
|---|---|---|
| 内部碎片 | 分配块比实际需求大,内部浪费 | 减小分配粒度 |
| 外部碎片 | 空闲内存分散,无法满足大块申请 | 内存紧缩(Compaction)/ 分页 |
内存对齐
CPU 读取内存时按字长对齐效率最高:
// 结构体对齐示例
struct A {
char a; // 1 byte + 3 byte padding
int b; // 4 bytes
}; // 共 8 bytes,不是 5 bytes- 成员按自身大小对齐
- 结构体总大小是最大成员大小的整数倍
#pragma pack(1)可强制紧凑排列(牺牲访问效率)
虚拟内存(swap)
物理内存不足时,OS 将不活跃的页换出到磁盘(swap 分区 / 页面文件),腾出物理内存给当前程序使用。
频繁换页 = 抖动(Thrashing),性能急剧下降,表现为 CPU 利用率低但系统极慢。