Linux 内存管理(Memory)
下面是一份 「内核级视角」Linux 内存管理(Memory)核心子系统详解。
不是 free/top 用法,而是从硬件 -> 内核数据结构 -> 页分配 -> 虚拟内存 -> NUMA -> OOM -> 容器的完整认知体系。
适用 RHEL / AlmaLinux / Debian / Ubuntu / 云 / 容器 / 数据库 / 虚拟化。
在“有限物理内存 + 大量进程 + IO 并发”的条件下,实现:
- 隔离(每进程独立地址空间)
- 高效(尽量命中缓存)
- 可回收(随时 reclaim)
- 可控制(cgroup / NUMA)
CPU
├─ L1/L2/L3 Cache
├─ MMU / TLB
└─ RAM
└─ Swap(磁盘)
📌 Linux 的内存管理 强依赖 MMU
- 默认页大小:4KB
- 大页:2MB / 1GB(HugePage)
struct page {
unsigned long flags;
atomic_t _refcount;
...
}
Linux 给每个进程一个“假想无限大”的内存空间
0x00000000 ────────── user space
heap
mmap
stack
0xC0000000 ────────── kernel space
- 每进程独立
- 内核空间共享
虚拟地址 -> 页表 -> 物理页 -> cache -> RAM
由 MMU + 页表 + TLB 完成
struct mm_struct {
pgd_t *pgd;
unsigned long total_vm;
unsigned long rss;
struct vm_area_struct *mmap;
}
struct vm_area_struct {
unsigned long vm_start;
unsigned long vm_end;
unsigned long vm_flags;
}
📌 mmap / heap / stack 都是 VMA
- 管理 2^n 页块
- 快速分配 / 合并
Order 0 = 1 page
Order 1 = 2 pages
Order 10 = 1024 pages
- 外部碎片
- 解决方案:
- 内存压缩(compaction)
- HugePage 预留
避免频繁 page 分配
- slab:老
- slub:默认(RHEL / Ubuntu)
用于:
- inode
- dentry
- task_struct
文件 IO 的缓存层
- 读:磁盘 -> page cache -> 进程
- 写:进程 -> page cache -> 异步刷盘
📌 free 内存 ≠ 可用内存
- dirty_ratio
- dirty_background_ratio
vm.dirty_ratio=20
vm.dirty_background_ratio=10
- 回收匿名页
- 防止 OOM
vm.swappiness=10
- 数据库:低
- 桌面:高
Active / Inactive
Anon / File
| 类型 | 触发 |
|---|---|
| kswapd | 后台 |
| direct | 分配失败 |
📌 direct reclaim 会卡业务
- reclaim 失败
- swap 不足
oom_score
oom_score_adj
cgroup 内存限制触发 OOM,不影响宿主
Node0 ←-> Node1
- 本地内存快
- 远程慢
- 自动页迁移
- 数据库通常关闭
- 2MB / 1GB
- 减少 TLB miss
- 自动
- 数据库一般禁用
echo never > /sys/kernel/mm/transparent_hugepage/enabled
- memory.max
- memory.high
- memory.swap.max
- OOM confined
- 优先 kill 容器内
- 看见的是“虚拟限制”
- page cache 可共享
- 双重页表(EPT)
- ballooning
✅ cache 可回收
✅ 没 swap 更容易 OOM
✅ DB 常常抖动
vm.swappiness
vm.overcommit_memory
vm.dirty_ratio
vm.dirty_background_ratio
vm.max_map_count
Linux 内存管理 = 虚拟内存 + 页表 + 页分配器 + Page Cache + Reclaim + OOM + NUMA + cgroup