Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Linux 内存管理(Memory)

下面是一份 「内核级视角」Linux 内存管理(Memory)核心子系统详解

不是 free/top 用法,而是从硬件 -> 内核数据结构 -> 页分配 -> 虚拟内存 -> NUMA -> OOM -> 容器的完整认知体系。

适用 RHEL / AlmaLinux / Debian / Ubuntu / 云 / 容器 / 数据库 / 虚拟化

一、Linux 内存管理的总体目标

在“有限物理内存 + 大量进程 + IO 并发”的条件下,实现:

  • 隔离(每进程独立地址空间)
  • 高效(尽量命中缓存)
  • 可回收(随时 reclaim)
  • 可控制(cgroup / NUMA)

二、从硬件开始:物理内存模型

1️⃣ RAM + Cache + Swap

CPU
 ├─ L1/L2/L3 Cache
 ├─ MMU / TLB
 └─ RAM
     └─ Swap(磁盘)

📌 Linux 的内存管理 强依赖 MMU

2️⃣ 页(Page)是最小单位

  • 默认页大小:4KB
  • 大页:2MB / 1GB(HugePage)
struct page {
    unsigned long flags;
    atomic_t _refcount;
    ...
}

三、虚拟内存(VM)核心思想

Linux 给每个进程一个“假想无限大”的内存空间

1️⃣ 虚拟地址空间

0x00000000 ────────── user space
            heap
            mmap
            stack
0xC0000000 ────────── kernel space
  • 每进程独立
  • 内核空间共享

2️⃣ 地址转换(关键路径)

虚拟地址 -> 页表 -> 物理页 -> cache -> RAM

MMU + 页表 + TLB 完成

四、内核核心数据结构

1️⃣ mm_struct(进程内存视图)

struct mm_struct {
    pgd_t *pgd;
    unsigned long total_vm;
    unsigned long rss;
    struct vm_area_struct *mmap;
}

2️⃣ VMA(虚拟内存区域)

struct vm_area_struct {
    unsigned long vm_start;
    unsigned long vm_end;
    unsigned long vm_flags;
}

📌 mmap / heap / stack 都是 VMA

五、页分配器(Buddy System)

1️⃣ Buddy 分配原理

  • 管理 2^n 页块
  • 快速分配 / 合并
Order 0 = 1 page
Order 1 = 2 pages
Order 10 = 1024 pages

2️⃣ 内存碎片问题

  • 外部碎片
  • 解决方案:
    • 内存压缩(compaction)
    • HugePage 预留

六、Slab / Slub 分配器(对象级)

避免频繁 page 分配

  • slab:老
  • slub:默认(RHEL / Ubuntu)

用于:

  • inode
  • dentry
  • task_struct

七、Page Cache(性能核心)

1️⃣ Page Cache 是什么

文件 IO 的缓存层

  • 读:磁盘 -> page cache -> 进程
  • 写:进程 -> page cache -> 异步刷盘

📌 free 内存 ≠ 可用内存

2️⃣ 脏页(Dirty Page)

  • dirty_ratio
  • dirty_background_ratio
vm.dirty_ratio=20
vm.dirty_background_ratio=10

八、Swap(不是洪水猛兽)

1️⃣ Swap 的作用

  • 回收匿名页
  • 防止 OOM

2️⃣ Swappiness

vm.swappiness=10
  • 数据库:低
  • 桌面:高

九、内存回收(Reclaim)

1️⃣ LRU 链表

Active / Inactive
Anon / File

2️⃣ kswapd vs direct reclaim

类型 触发
kswapd 后台
direct 分配失败

📌 direct reclaim 会卡业务

十、OOM Killer(最后防线)

1️⃣ OOM 触发条件

  • reclaim 失败
  • swap 不足

2️⃣ OOM 评分

oom_score
oom_score_adj

3️⃣ 容器 OOM

cgroup 内存限制触发 OOM,不影响宿主

十一、NUMA 内存管理

1️⃣ NUMA 节点

Node0 ←-> Node1
  • 本地内存快
  • 远程慢

2️⃣ NUMA balancing

  • 自动页迁移
  • 数据库通常关闭

十二、HugePages(数据库重点)

1️⃣ HugeTLB

  • 2MB / 1GB
  • 减少 TLB miss

2️⃣ Transparent Huge Pages(THP)

  • 自动
  • 数据库一般禁用
echo never > /sys/kernel/mm/transparent_hugepage/enabled

十三、cgroups v2 内存控制

1️⃣ 控制项

  • memory.max
  • memory.high
  • memory.swap.max

2️⃣ OOM 行为变化

  • OOM confined
  • 优先 kill 容器内

十四、内存与容器 / 虚拟化

容器

  • 看见的是“虚拟限制”
  • page cache 可共享

虚拟机

  • 双重页表(EPT)
  • ballooning

十五、常见误区纠正

❌ free 显示内存用完了

✅ cache 可回收

❌ swap 一定慢

✅ 没 swap 更容易 OOM

❌ THP 一定好

✅ DB 常常抖动

十六、关键内核参数速查

vm.swappiness
vm.overcommit_memory
vm.dirty_ratio
vm.dirty_background_ratio
vm.max_map_count

十七、总结

Linux 内存管理 = 虚拟内存 + 页表 + 页分配器 + Page Cache + Reclaim + OOM + NUMA + cgroup