Linux 系统下,应用程序运行在一个虚拟地址空间中,所以程序中读写的内存地址对应也是虚拟地址,并不是真正的物理地址,譬如应用程序中读写 0x80800000 这个地址,实际上并不对应于硬件的 0x80800000这个物理地址。
为什么需要引入虚拟地址呢?
计算机物理内存的大小是固定的,就是计算机的实际物理内存, 试想一下,如果操作系统没有虚拟地址机制,所有的应用程序访问的内存地址就是实际的物理地址, 所以要将所有应用程序加载到内存中,在32位系统中实际访问的物理内存只有4G,所以就会出现一些问题:
- 当多个程序需要运行时,必须保证这些程序用到的内存总量要小于计算机实际的物理内存的大小。
- 内存使用效率低。内存空间不足时,就需要将其它程序暂时拷贝到硬盘中,然后将新的程序装入内存。然而由于大量的数据装入装出,内存的使用效率就会非常低。
- 进程地址空间不隔离。由于程序是直接访问物理内存的,所以每一个进程都可以修改其它进程的内存数据, 甚至修改内核地址空间中的数据,所以有些恶意程序可以随意修改别的进程,就会造成一些破坏,系统不安全、不稳定。
- 无法确定程序的链接地址。 程序运行时,链接地址和运行地址必须一致,否则程序无法运行!因为程序代码加载到内存的地址是由系统随机分配的,是无法预知的, 所以程序的运行地址在编译程序时是无法确认的。
针对以上的一些问题,就引入了虚拟地址机制, 程序访问存储器所使用的逻辑地址就是虚拟地址,通过逻辑地址映射到真正的物理内存上。 所有应用程序运行在自己的虚拟地址空间中, 使得进程的虚拟地址空间和物理地址空间隔离开