1、内存分配的全过程

一、总览:从 malloc 到真正的内存

当你在 C 程序中写下:

void *p = malloc(1024);

这一行表面上是在“申请 1KB 内存”,
但本质上,这只是向操作系统登记了 1KB 虚拟地址空间
并没有真正分配物理内存

真正的物理内存分配,要等到程序第一次访问这块虚拟地址时才发生。


二、阶段一:用户态调用 malloc

1. malloc() 的行为

  • malloc 向操作系统申请 虚拟内存空间
    通常通过 brk()mmap() 完成。
  • 内核只在进程的虚拟地址空间中标记:“这块地址可用”,
    并在页表中标注“尚未分配物理页”。

此时的状态:

虚拟内存:✔ 已分配
物理内存:❌ 还没有
页表映射:❌ 尚未建立

类比:
你向房东预订了一间房(malloc),但还没真正入住,
房东只在名册上写下“这间房给你留着”。


三、阶段二:第一次访问内存 → 触发缺页中断

当程序第一次读或写这块内存时(例如 *p = 1;):

  1. CPU 查页表,发现该虚拟页没有对应的物理页(P=0);
  2. 于是触发 Page Fault(缺页中断)
  3. 进程从 用户态切换到内核态
    内核的 Page Fault Handler(缺页中断处理函数)接管控制。

四、阶段三:缺页中断处理流程

缺页中断处理函数负责让虚拟页真正“落地”成物理页:

  1. 检查内存是否有空闲页
    • 若有:直接分配;
    • 若无:启动内存回收机制。
  1. 分配物理页并建立映射
    • 分配一页物理内存;
    • 更新页表,将该虚拟页映射到物理页;
    • 设置访问权限(可读/可写/用户态)。
  1. 恢复用户态执行
    • 进程回到用户态;
    • 重新执行刚才那条导致缺页的指令。

此时:

虚拟内存:✔ 已分配
物理内存:✔ 已分配
页表映射:✔ 已建立

类比:
你终于去酒店前台登记入住(缺页中断),
前台分配了真正的房间钥匙(物理页),
并在系统中建立“房号–住客”的对应表(页表)。


五、阶段四:内核回收机制(当内存不够时)

如果系统找不到空闲物理页,内核就要“挤一挤”:

1. 后台回收(kswapd)

  • 内核线程 kswapd 异步运行;
  • 当系统检测到内存紧张时被唤醒;
  • 回收不常用的页(LRU 策略),写回磁盘(Swap),释放物理页;
  • 异步进行,不阻塞进程。

2. 直接回收(direct reclaim)

  • 当进程申请内存速度太快,后台跟不上;
  • 当前进程会被阻塞,等待内核同步释放页;
  • 这是“紧急”同步回收机制。

3. 仍然不够:触发 OOM(Out Of Memory)

  • 如果两种回收方式都无法腾出空间;
  • 内核启动 OOM Killer(内存溢出杀手);
  • 选择内存占用大的进程并强制杀死,以释放资源;
  • 若仍不足,会持续杀进程,直到系统恢复。

优先级规则(简化):

  • 内存占用高;
  • 权重低(非系统关键进程);
  • 用户态程序优先被杀。

六、阶段五:总结整个路径

1️⃣ 程序申请

→ malloc() 调用 → 虚拟地址空间扩大
(通过 brk/mmap,尚未映射物理页)

2️⃣ 程序访问

→ CPU 查页表 → 发现页不存在 → 缺页中断
→ 进入内核态

3️⃣ 内核分配

→ 分配物理页 → 更新页表 → 返回用户态

4️⃣ 程序继续执行

→ 虚拟地址与物理地址正式对应,读写正常


七、内存分配过程简图

用户空间 (User Space)
┌──────────────────────────────┐
│ malloc()                     │
│  ↓                            │
│ 分配虚拟内存 (未映射)          │
│  ↓                            │
│ 第一次访问 → 缺页中断          │
│  ↓                            │
│ 内核分配物理页 + 建立映射       │
│  ↓                            │
│ 用户继续执行                   │
└──────────────────────────────┘
            │
            ▼
内核空间 (Kernel Space)
┌──────────────────────────────┐
│ Page Fault Handler            │
│  ├─ 查找空闲页                │
│  ├─ 无页 → kswapd 回收        │
│  ├─ 再无页 → OOM Killer        │
│  └─ 更新页表映射              │
└──────────────────────────────┘

八、形象类比总结

阶段

技术行为

生活类比

malloc()

申请虚拟内存

预定房间

第一次访问

缺页中断

你到前台登记入住

Page Fault Handler

分配物理页

前台分配房间并登记

kswapd

后台清理旧房

清理空房间以供入住

direct reclaim

你等清洁工打扫完才能入住

同步等待

OOM Killer

房间爆满时赶走住客

强制清理占用者


九、一句话总结

malloc 分配的是虚拟内存,不是物理内存;
第一次访问才触发缺页中断,由内核分配物理页并建立映射;
若内存紧张,内核通过 kswapd → direct reclaim → OOM Killer 三层机制逐步回收。

完整路径:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值