2.内核空间里面的PCB是所有进程的吗?每个进程都有丢虚拟地址空间吗?如果都有虚拟地址空间总大小是不是完全加起来?

📅 2026/7/22 3:50:42
2.内核空间里面的PCB是所有进程的吗?每个进程都有丢虚拟地址空间吗?如果都有虚拟地址空间总大小是不是完全加起来?
1. 每个进程都有自己的虚拟地址空间吗✅ 是的。每创建一个进程Linux都会给它建立一个独立的虚拟地址空间。例如有三个进程进程A | ↓ 虚拟地址空间A 进程B | ↓ 虚拟地址空间B 进程C | ↓ 虚拟地址空间C它们看到的地址可以完全一样。例如进程Amain函数地址 0x400500进程Bmain函数地址 0x400500看起来一样。但是进程A: 0x400500 | ↓ 物理内存A 进程B: 0x400500 | ↓ 物理内存B靠页表Page Table MMU区分。2. 那每个进程的虚拟地址空间里面都有PCB吗这里是一个容易误解的地方。❌ 不是。准确说PCB属于内核空间但是不是放在每个进程自己的用户空间里面。Linux里面叫task_struct它就是PCB。例如物理内存 ---------------- | | | Linux Kernel | | | | task_struct A | ← A进程PCB | task_struct B | ← B进程PCB | task_struct C | ← C进程PCB | | ----------------所有进程的PCB都由内核统一管理。3. 那为什么说每个进程虚拟地址空间里面有内核空间这里容易误会。比如进程A虚拟地址空间 ---------------- | 内核空间 | | | | task_struct ? | ---------------- | 用户空间 | | | | main() | | heap | | stack | ----------------看起来好像PCB就在这里面实际上不是。这里的“内核空间”指这个进程切换到内核态时可以访问的内核地址映射。例如进程A用户态: 访问用户空间 系统调用: 进入内核态 看到同一份内核映射而不是每个进程复制一份内核空间4. 所有进程的虚拟地址空间加起来是不是很大这里分两个概念。1虚拟空间大小虚拟地址空间大小主要取决于CPU位数和操作系统设计不是由物理内存大小决定的。虚拟地址空间 CPU地址线能够表示的地址范围。1. 32位系统32位 CPU地址长度2^{32}所以虚拟地址空间4GB例如32位进程虚拟地址空间 0x00000000 | | | 4GB | 0xffffffffLinux通常划分用户空间 3GB ---------------- 内核空间 1GB也就是经典---------------- | Kernel 1GB | ---------------- | User 3GB | ----------------所以32位程序最大通常只能使用约3GB用户空间。2. 64位系统现在主流x86-64ARM64理论地址2^{64}也就是16EB1EB1024PB非常巨大16EB 16777216TB但是实际上CPU不会真的使用64位全部地址。Linux x86-64实际情况目前常见用户空间约128TB内核空间约128TB结构64位 Linux进程虚拟地址空间 0x00007fffffffffff ---------------- | | | 用户空间 | | 128TB | | | ---------------- 空洞 ---------------- | | | 内核空间 | | 128TB | | | ---------------- 0xffffffffffffffff3. 为什么不是16EB因为CPU虽然64位但是实际地址线没有64位。例如x86-64目前常见虚拟地址48位物理地址40~52位所以虚拟地址2^{48}256TBLinux一般用户 128TB 内核 128TB刚好256TB4. 一个进程真的占128TB内存吗❌ 不占。这是最大的误区。比如运行int main() { while(1); }这个程序可能虚拟空间128TB但是实际代码 几十KB 栈 几MB 堆 0实际物理内存可能几MB。5. malloc为什么可以申请很大例如char *p malloc(1TB);可能不会马上失败。因为malloc只是虚拟地址空间划一块区域例如虚拟空间 ---------------- | | | malloc 1TB | | | ----------------真正访问p[0]a;才分配物理页虚拟地址 | ↓ 页表 | ↓ 物理内存页6. 和PCB有什么关系例如100个进程每个128TB虚拟空间理论100 × 128TB 12800TB但是实际RAM比如16GB完全没问题。因为虚拟地址空间只是每个进程自己的地址编号体系。不是真正占用的内存。系统单个进程虚拟地址空间32位 Linux4GB用户约3GB64位 Windows/Linux 常见128TB用户空间64位理论16EB实际物理内存几十GB~TB一个64位 Linux进程通常拥有约128TB用户虚拟地址空间但真正使用的可能只有几十MB到几十GB虚拟空间是“地址地图”不是实际内存。2实际物理内存例如你的电脑16GB RAM即使100个进程 每个虚拟空间128TB也不可能真的占12800TB内存因为虚拟地址只是一个“地图”。5. 举个生活例子虚拟地址空间像酒店房间编号。酒店10000个房间编号但是实际酒店100间房编号存在 ≠ 房间真的建好了。同理虚拟地址0x0000000000400000只是一个编号。实际物理页可能还没分配共享换出磁盘6. 那内核空间是不是每个进程一份更准确虚拟上每个进程都有用户空间 内核空间映射物理上内核代码只有一份例如进程A页表 | ↓ Linux kernel 进程B页表 | ↓ 同一个Linux kernel这样节省内存方便系统调用7. 最终关系图CPU | 当前运行进程A A进程虚拟地址空间 ---------------- | 内核空间 | | | | 共享kernel | ---------------- | 用户空间 | | | | code | | heap | | stack | ---------------- 内核管理区域 ---------------- | task_struct A | | task_struct B | | task_struct C | | 页表 | | 调度器 | ----------------每个进程都有自己的虚拟地址空间但PCB(task_struct)不是放在进程自己的虚拟空间里而是在内核空间中由操作系统统一管理。所有进程看到的内核空间映射基本相同PCB数量等于进程数量但不会随着虚拟地址空间简单相加占用真实内存。