跳到主要内容
Linux 内存分布结构:物理、虚拟与进程布局 | 极客日志
C
Linux 内存分布结构:物理、虚拟与进程布局 Linux 内存管理涉及物理内存、虚拟内存及用户进程布局三个核心层次。物理内存是硬件存储,通过页表映射到虚拟地址空间。内核空间与用户空间隔离,用户进程拥有独立的代码段、数据段、堆栈等区域。MMU 负责地址转换,支持内存保护、多任务并发及扩展性。通过 Swap 机制利用磁盘模拟更多内存,解决物理限制问题。掌握这些结构有助于理解操作系统内核行为及性能优化。
lzdxwyh 发布于 2025/11/22 更新于 2026/10/24 111 浏览Linux 系统的内存分布结构及其之间的关系
Linux 系统的内存分布结构(memory layout / memory organization)是理解操作系统内核、驱动、应用程序内存管理的基础之一 。下面将从宏观到微观、从物理内存到虚拟内存 的角度,系统地梳理整个结构。
一、整体框架:物理内存 vs 虚拟内存
类型 说明 典型范围(x86_64) 物理内存(Physical Memory) 实际存在的内存条上的存储空间 0x0000_0000 ~ 物理 RAM 最大地址 虚拟内存(Virtual Memory) 每个进程或内核看到的逻辑地址空间,由 MMU 映射到物理内存 用户态通常 0x0000_0000_0000_0000 ~ 0x0000_7fff_ffff_ffff
Linux 中每个进程看到的虚拟内存空间都是独立的,通过 页表(Page Table) 映射到共享的物理内存。
二、Linux 内核视角下的内存布局
(1)物理内存布局
在 Linux 启动后,物理内存被划分为以下几个区域(在 /proc/zoneinfo 可以看到):
区域名 作用 对应体系结构 ZONE_DMA 旧式设备需要的低端物理内存(<16MB) x86 等老平台 ZONE_DMA32 需要 32 位地址的 DMA 设备使用(<4GB) x86_64 平台 ZONE_NORMAL 普通内存区,内核直接映射 通常从 4GB 开始 ZONE_HIGHMEM 高端内存,内核需要临时映射才能访问(32 位系统) 仅 32 位平台
在 64 位 Linux 系统上,通常没有 HIGHMEM,因为虚拟地址空间够大,全部物理内存都可以直接映射。
(2)虚拟地址空间布局(内核空间)
Linux 内核的虚拟地址空间分为:
区域 作用 典型地址(x86_64) 内核空间 (kernel space) 共享于所有进程,由内核使用 ffff800000000000 ~ ffffffffffffffff直接映射区 (direct mapping region) 将所有物理内存映射到虚拟空间 通常 ffff888000000000 开始 vmalloc 区 动态分配非连续物理内存的虚拟区域 ffffc90000000000 ~
ffffe8ffffffffff
模块加载区 (module region) 内核模块加载的虚拟地址 ffffffffa0000000 等
fixmap 区 固定映射的一些特殊页(如 APIC、IO 空间) 高端地址附近
三、用户进程的虚拟内存布局 每个用户进程的虚拟地址空间大致如下(可通过 /proc/<pid>/maps 查看):
+--------------------------+ 高地址
| stack (栈区) | <-- 向下增长
+--------------------------+
| mmap() 映射区 |
| (共享库、匿名映射等) |
+--------------------------+
| heap (堆区) | <-- malloc/brk 向上增长
+--------------------------+
| data 段 (已初始化全局变量)|
+--------------------------+
| bss 段 (未初始化全局变量) |
+--------------------------+
| text 段 (代码段、只读区) |
+--------------------------+
| NULL (未映射区) |
+--------------------------+ 低地址
用户空间和内核空间之间通常以 TASK_SIZE 分界,比如:
32 位系统:TASK_SIZE = 0xC0000000(3GB 用户 + 1GB 内核)
64 位系统:用户空间最大约 128TB 左右(取决于架构)
四、页表与地址转换 CPU 通过 MMU(内存管理单元) 把虚拟地址转换为物理地址。Linux 使用 多级页表结构 (4 级或 5 级):
虚拟地址 ↓ PGD → P4D → PUD → PMD → PTE → 物理页帧
每一级页表指向下一层的页表基址。每个页的典型大小:
普通页:4KB
大页(HugePage):2MB 或 1GB
五、查看与分析命令 命令 用途 cat /proc/meminfo系统内存总览 cat /proc/zoneinfo内存分区(ZONE)详情 cat /proc/iomem物理内存映射 free -h查看系统内存使用 vmstat, top, htop动态查看内存 pmap <pid>查看进程虚拟内存分布 cat /proc/<pid>/maps进程内存映射详情
六、简化示意图(x86_64) 物理内存:
+-------------------------+
| BIOS/设备保留区 | < 1MB
+-------------------------+
| DMA 区 (ZONE_DMA) | < 16MB
+-------------------------+
| DMA32 区 (ZONE_DMA32) | < 4GB
+-------------------------+
| 普通区 (ZONE_NORMAL) | > 4GB
+-------------------------+
内核虚拟地址空间:
ffff800000000000 ───────────────
│ fixmap, modules, vmalloc │
│ direct mapping of all RAM│
│ 内核页表、堆栈、代码、数据等│
├───────────────────────────────
0000000000000000 ───────────────
│ 用户空间 (text, data, heap,│
│ stack, mmap, libc, etc.) │
└───────────────────────────────
这三个概念之间确实容易混淆,但它们其实是**'同一个内存系统在不同抽象层次上的三种视角'**。
七、三者的逻辑关系(由底向上) 物理内存(Physical Memory)
↑
│ MMU 页表映射(页级映射、权限控制)
│
虚拟内存(Virtual Memory)
↑
│ 内核为不同进程划分虚拟地址空间(空间隔离)
│
虚拟地址空间布局(Address Space Layout)
↑
│ 每个进程看到的内存分布(代码段/堆/栈)
│
用户进程的虚拟内存布局(User Process Memory Layout)
物理内存 是硬件层面上真实存在的存储单元;
虚拟内存 是 CPU + OS 提供的逻辑抽象,让每个进程都'以为自己独占整块内存';
虚拟地址空间布局 是虚拟内存被 OS 组织的结构;
用户进程的虚拟内存布局 是其中'属于用户态部分'的子集。
八、逐层详解与对应关系
1. 物理内存(Physical Memory)
硬件真实存在 :即 DRAM 芯片中的存储单元。
每个物理页帧有一个编号(PFN,Page Frame Number)。
OS 通过 页表 把'虚拟页'映射到'物理页帧'。
物理地址: [0x00000000 - 0x001FFFFF] -> 2 MB
[0x00200000 - 0x003FFFFF] -> 2 MB
...
2. 虚拟内存(Virtual Memory)
由 MMU(内存管理单元) + 页表(page table) 实现。
每个进程拥有独立的虚拟地址空间(通常 64 位系统为 128TB)。
虚拟页(Virtual Page)通过页表映射到物理页(Physical Page)。
🧩 关键特征:隔离 + 保护
每个进程互不干扰;访问非法页 → 触发页错误(segfault)。
3. 虚拟地址空间布局(Address Space Layout)
用户空间(User Space)
内核空间(Kernel Space)
用户空间: 0x0000_0000_0000_0000 ~ 0x0000_7fff_ffff_ffff
内核空间: 0xffff_8000_0000_0000 ~ 0xffff_ffff_ffff_ffff
这称为虚拟地址空间布局 。它描述了'整个虚拟内存范围'的全局分布。
4. 用户进程的虚拟内存布局(User Process Memory Layout) 区域 说明 典型增长方向 text 程序代码段 固定 data 已初始化的全局变量 固定 bss 未初始化的全局变量 固定 heap 动态分配区(malloc/brk) 向上增长 ↑ mmap 动态映射区(共享库/匿名映射) 向下增长 ↓ stack 线程栈 向下增长 ↓
高地址
+------------------+
| Stack | 向下增长
+------------------+
| Mapped files |
+------------------+
| Heap | 向上增长
+------------------+
| BSS, Data, Text | 低地址
九、三者之间的关系总结 层次 描述 映射/包含关系 物理内存 真正的 RAM 硬件 被'页表'映射到虚拟内存 虚拟内存 OS 提供的逻辑内存抽象 由物理页 + 交换区(swap)组成 虚拟地址空间布局 整个虚拟内存空间的结构(用户 + 内核) 定义虚拟内存的全局分区 用户进程虚拟内存布局 用户空间部分的细分结构(代码、堆、栈等) 是虚拟地址空间的一部分
十、举个例子:进程访问内存时的路径 1️⃣ p 是一个 虚拟地址 (属于用户虚拟空间)。
2️⃣ MMU 查页表 → 得到对应的 物理页帧号(PFN) 。
3️⃣ 访问该物理页中的内容。
4️⃣ 如果该页还没在内存中(比如在磁盘 swap),会触发缺页中断 ,由内核加载后再返回。
虚拟地址(用户视角)
↓ 页表映射
物理地址(硬件视角)
↓ 存取 DRAM
实际数据
👉 虚拟内存(Virtual Memory) 是操作系统为了解决'内存有限、程序多样、安全隔离、方便编程'等问题而引入的抽象层 。
它让每个进程都'以为'自己拥有独立且连续的完整内存空间。
十一、为什么需要虚拟内存(动机)
程序 A 加载到物理地址 0x00000000
程序 B 加载到物理地址 0x00100000
问题 说明 ① 内存冲突问题 不同程序可能访问同一物理地址,互相覆盖数据。 ② 内存分配困难 程序加载地址不连续,碎片化严重。 ③ 安全隔离困难 程序可以随意访问别的程序或内核空间。 ④ 多任务调度麻烦 程序切换时需要保存和恢复物理地址映射。 ⑤ 扩展性差 程序必须适应'物理内存大小限制'。
于是,操作系统与硬件设计者提出了一个'虚拟化'的方案👇
✅ '让每个进程看到的地址空间都一样,但实际背后映射到不同的物理内存。'
十二、虚拟内存的核心思想
1️⃣ 地址虚拟化(Address Virtualization) 每个进程看到的内存空间是'虚拟地址空间',
通过 MMU(Memory Management Unit) + 页表(Page Table)
把虚拟地址 → 物理地址 映射。
🧩 每个进程都以为:
实际上不同进程的 0x00000000 会被映射到不同的物理页。
2️⃣ 页式管理(Paging)
虚拟内存页(Virtual Page)
物理页帧(Physical Frame)
虚拟内存可以不连续
物理内存可以动态调度
程序可以只加载部分页
3️⃣ 结合磁盘(Swap / Page Cache) 虚拟内存不仅映射到物理 RAM,也可以映射到磁盘文件 或交换区(swap) 。
当物理内存不足时,不常用的页可以被换出(swap out),
再次访问时再换入(page fault + swap in)。
🧠 这让程序'看起来'拥有的内存空间远大于实际物理内存!
十三、虚拟内存带来的主要优势 目的 描述 举例 ✅ 内存保护(隔离) 每个进程拥有独立的地址空间,互不干扰 程序 A 无法访问程序 B 的内存 ✅ 简化编程模型 程序认为自己有连续内存,不需关心物理碎片 数组/指针可直接用线性地址 ✅ 支持多任务并发 操作系统可自由调度不同进程,共享物理内存 任务切换只需切页表 ✅ 内存扩展(虚拟化) 可以使用磁盘模拟更多内存 即使 RAM 只有 8GB,也能运行 10GB 程序 ✅ 共享内存机制 允许部分页映射到相同物理页 多进程共享 libc.so 库 ✅ 高效 I/O 映射 设备寄存器、文件可映射到地址空间 mmap() 机制
十四、举个直观例子 假设你的电脑只有 4GB RAM ,
但你同时运行:
Chrome:需要 2GB
VSCode:需要 1GB
Python:需要 2GB
物理内存总需求 5GB > 实际 4GB
👉 通过虚拟内存:
进程 虚拟地址空间 实际物理页 交换区(磁盘) Chrome 8GB 部分页驻留 RAM 冷页换出 VSCode 8GB 部分页驻留 RAM 冷页换出 Python 8GB 部分页驻留 RAM 冷页换出
每个进程都认为自己'拥有'8GB 地址空间,
但 OS 只把当前活跃的部分页保留在 RAM 中,
其他暂时不用的页放到磁盘中。
十五、简化结构图(逻辑示意) 用户视角 (虚拟地址空间)
+------------------------------+
| Stack | Heap | Data | Text |
+------------------------------+
↓ 页表映射
+------------------------------+
| 部分在物理 RAM |
| 部分在磁盘 Swap |
+------------------------------+
物理视角 (真实内存 + 磁盘)
十六、总结一句话 层次 没有虚拟内存时 有了虚拟内存后 内存访问 程序直接操作物理地址 程序操作虚拟地址,系统自动映射 程序隔离 相互影响、容易崩溃 地址空间隔离、安全 内存利用 碎片化严重 灵活调度、支持换页 程序设计 复杂、需考虑实际地址 简单、线性逻辑
相关免费在线工具 Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
JSON美化和格式化 将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online