目录
一、虚拟内存地址
1.为什么要有虚拟内存地址?
因为如果CPU直接访问物理内存,那如果两个进程写入一个物理地址,那值就会改变。对于一个操作系统而言,一个重要任务就是做地址隔离。操作系统为每个进程分配一套独立的虚拟地址,这样每个进程互不干涉。
应用程序中使用的地址是虚拟内存地址,实际存在于硬件里面的地址是物理内存地址。至于虚拟内存如何对应到物理内存,是由CPU芯片中的内存管理单元(MMU)实现。
内存映射主要有分段和分页的形式, 分段时每一段大小不统一,导致内存碎片和内存交换效率低,因此,Linux系统主要采用分页,每页4KB,不会产生细小的内存碎片,内存交换写入硬盘的也只有一页或几页。但由于Intel处理器历史原因,分段不可避免,被用于访问控制和内存保护。
对于分页,简单分页产生的页表过大的问题,就有了多级页表,但这就会导致 CPU 在寻址的过程中需要有很多层表参与,加大了时间上的开销。于是 CPU 芯片中加入了 TLB,负责缓存最近常被访问的页表项,大大提高了地址的转换速度。
2.虚拟地址好处
虚拟地址好处:
- 避免用户直接访问物理地址,保护系统;
- 进程间安全;
- 内存分配和释放更方便:不连续几块儿物理内存可以映射到连续的一块虚拟内存;
- 各进程分配之和可以大于实际可用的物理内存。
二、用户空间和内核空间
1.概念
这里所说的用户空间和内核空间指的都是上面所说的虚拟地址空间,物理地址不用我们去考虑。
虚拟地址空间实现了进程的隔离。
以32位linux操作系统为例,每个进程被分配4GB的虚拟内存,因为一个指针长度是 4 字节,将虚拟地址空间的最高的1G字节(从虚拟地址 0xC0000000 到 0xFFFFFFFF )供内核使用,称为内核空间,而较低的 3G 字节(从虚拟地址 0x00000000 到0xBFFFFFFF),供各个进程使用,称为用户空间。用户空间是独立的,而内核空间是共有的,进程切换时,用户空间切换,内核空间不变。
2.用户态和内核态
当一个任务(进程)执行系统调用而进入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)此时处理器处于特权级最高的(0级)内核代码中执行。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。处理器在特权等级高的时候才能执行那些特权CPU指令。
3.IPC通信原理
比如有三个进程A、B、C。内核空间是共用的,用户空间是每个进程私有的:
如果你想不同进程传输数据,直接传是不行的,要通过内核空间,这就是IPC通信:
之后会推出IPC通信“一文学会”系列文章。
参考优秀博客: