1 概念
物理地址:是内存芯片上的绝对硬件地址,直接对应着数据在内存条上的物理存储单元。
虚拟地址:是每个进程看到的、由操作系统提供的抽象化、隔离化的地址空间。
地址映射:CPU和操作系统通过内存管理单元(MMU)和页表(Page Table)协作,将进程使用的虚拟地址动态地映射到实际的物理地址上。
2 地址映射:虚拟地址 -> 物理地址
当进程中的代码执行一条指令(如
mov eax, [0x12345678])时,CPU生成的是一个虚拟地址(0x12345678)。CPU将这个虚拟地址发送给MMU。
MMU查询页表。页表由操作系统为每个进程单独维护,其作用就像一本“地址翻译字典”。
页表条目(Page Table Entry, PTE)中记录了该虚拟页面对应的物理页框号(Page Frame Number, PFN),以及权限位(是否可写、是否在物理内存中等)。
MMU将虚拟地址中的“页内偏移”部分直接拼接到找到的物理页框号上,最终得到物理地址。
MMU将这个物理地址发送到地址总线上,从而访问真正的物理内存。
3 其他概念
页(Page)
内存被划分为固定大小的块,称为“页”(通常为4KB)。虚拟地址空间和物理地址空间都按页来管理。地址转换也是以页为单位进行的。可以对内存页设置读、写、执行等权限,防止代码注入等攻击。
加速机制:TLB(Translation Lookaside Buffer)
由于页表存储在内存中,每次转换都需要访问内存,会非常慢。
TLB是MMU内部的一个小型高速缓存,用于存储最近使用过的虚拟页到物理页框的映射关系。当TLB命中时,转换无需访问内存,速度极快。这是提升性能的关键。
4 扩展信息
指针的本质
C++中的指针存储的是虚拟地址。你对一个指针解引用,CPU/MMU会自动完成到物理地址的转换。这解释了为什么一个错误的指针(如空指针、野指针)访问会导致段错误(Segmentation Fault)——MMU在转换时发现这个虚拟地址没有映射到合法的物理地址或者权限不足,会触发一个异常,操作系统据此终止你的程序以保护系统。
多线程与进程间通信
线程共享其所属进程的虚拟地址空间,所以线程间通过指针共享数据很容易。
进程拥有独立的虚拟地址空间,所以进程间通信(IPC)必须通过操作系统提供的特殊机制(如共享内存、管道、消息队列等)。共享内存的本质就是让两个进程的不同虚拟地址区域映射到同一块物理内存上。
核心转储(Core Dump)
当程序崩溃生成core文件时,里面记录的是进程崩溃瞬间的虚拟地址空间的镜像。调试器(如GDB)需要结合可执行文件和共享库的符号信息,才能将这些虚拟地址翻译成有意义的函数名和变量名。
评论区