虚拟地址
恰如其名,这个地址是虚拟的,与具体环境是解耦的,这样可以是程序员在编写程序时只需要关注代码逻辑本身,而不需要考虑地址分配。这些虚拟地址并不是真正运行在机器上的内存地址,每个程序的虚拟地址都是独立存在的,虚拟地址是逻辑上存在的一个数值。实际上我们在开发程序的过程中,软件程序经过编译后需要经过链接才能形成可执行程序,通过链接器将多个代码模块组装在一起,并解决模块之间的引用,即处理程序代码地址之间的引用问题,形成程序运行的静态内存空间视图。只不过这个地址是虚拟而统一的,而根据操作系统的不同,这个虚拟地址空间的定义也许不同,应用软件开发人员无需关心,由开发工具链给自动处理了。由于这虚拟地址是独立且统一的,所以各个公司开发的各个应用完全不用担心自己的内存空间被占用和改写。
物理地址
顾名思义,就是真实存在的地址,物理地址在逻辑上也是一个数据,只不过这个数据会被地址译码器等电子器件变成电子信号,放在地址总线上,说明地址总线上的信号就代表了物理地址,地址总线电子信号的各种组合就可以选择到内存的储存单元,同时也可以选择其它设备的储存单元,如显卡中的显存、I/O 设备中的寄存器、网卡上的网络帧缓存器。
虚拟地址与物理地址相互转换
通过上面的理解,我们知道,如果程序想要正常运行,必须将虚拟地址转换为物理地址,转换就需要一个转换结构或者转换函数,用软件的方式实现这个函数,效率比较低下,直接用硬件方式又不够灵活,于是就引入了软硬结合的方式——MMU(内存管理单元)。MMU 可以接受软件给出的地址对应关系数据,进行地址转换。
上图中展示了 MMU 通过地址关系转换表,将 0x80000~0x84000 的虚拟地址空间转换成 0x10000~0x14000 的物理地址空间,而地址关系转换表本身则是放物理内存中的。
如果将虚拟地址与物理地址一一对应,那么在实际开发过程中,我们会很快将物理地址给使用完,于是就引入了现代内存管理模式——分页模式,把虚拟地址空间和物理地址空间都分成同等大小的块,也称为页,按照虚拟页和物理页进行转换。根据软件配置不同,这个页的大小可以设置为 4KB、2MB、4MB、1GB