《程序员的自我修养》- 虚拟地址空间


虚拟地址空间一方面实现了操作系统中不同进程之间的相互隔离,一方面可以提高多任务的效率。

#分段

分段即将一段与进程所需要的空间大小一致的物理空间直接映射到虚拟地址空间中,这一方案虽然实现了进程之间的相互隔离,但直接使用物理地址时的低效率仍然存在。

#分页

分页的结果是提高了内存的颗粒度,其依据是程序的局部性原理,其目的是提高多进程运行的效率。

所谓“局部性原理”即程序在一定时间段内倾向于访问某一地址附近的内存。这既是程序的特性,也是程序员在设计程序时应该依据的准则。局部性强的程序缓存命中率高,运行速度也会得到相应提升。

页的大小由硬件决定,可能不唯一,由操作系统选择一个特定的大小。现在的操作系统一般选取0x1000字节(4KB)为一页的大小。

#内存管理单元MMU

MMU的作用是将虚拟内存中的虚拟页映射到物理内存中的物理页。它是一种内存映射的硬件实现,一般集成在CPU的内部。CPU发出的物理内存经过MMU的翻译后就变成了程序看到的虚拟内存。

#Linux 32位进程的虚拟地址空间

下面这个表格显示了32位进程的虚拟地址空间的结构(地址由下往上增长):

可以看到,该虚拟地址空间由上方黑色的内核空间和下方的用户空间组成。内核空间和用户空间分别占据总共4GB空间的一定比例。而下方的用户空间又可以大致分为两部分:ELF文件被装载的区域和用于存储进程运行时数据的其他区域(不准确)。

这张表格中体现出的安全机制同样值得一提。右方的标注“Random xxx offset”是使用了ALSR( Address space layout randomization)的标志,它可以将Stack区,Heap区,mmap区域以及libc装载的起始地址随机化,从而避免Return-to-libc等攻击方式。 与之类似的是PIE(Position Independent Executable),由于32位下ELF文件的默认基地址是0x8048000,这造成了bin文件泄露的危险,因此可以采用PIE技术随机化ELF文件的装载位置。 值得注意的是,ALSR技术与PIE技术目的虽然相似,但关系不大,在现代的操作系统中,即使编译时关闭PIE,ALSR依然存在。


疑问:以32位操作系统为例,可以访问的最大地址空间共4GB,那么每个进程的虚拟地址空间同样是4GB。现在假设物理内存的大小为4GB,那么当操作系统中运行多个进程时,内存岂不是要爆掉?

猜想: 首先,程序运行时并不会将虚拟地址空间完全用尽,因此完全可以维护一个映射表,它仅仅将虚拟地址空间中有效的虚拟页页映射到物理内存中的物理页上,而没有用到的虚拟页页就不进行映射,并且根据实际情况删除页的映射或者添加新映射 其次,每个进程使用到的数据也有可能是相同的,因此多个虚拟页可能映射到同一个物理页 综上所述,尽管进程的虚拟地址空间有4GB,但它用到的物理内存空间可能远远少于4GB


← Prev 《程序员的自我修养》- 线程 | 64位格式化字符串漏洞 Next →