Linux 核心--4.内存管理

第三章 存储管理

存储管理子系统时操作系统中最重要的组成部分之一 。在早期计算时代,由于人们所需要的内存数目远远大于物理内存,人们设计出了各种各样的策略来解决此问题,其中最成功的是虚拟内存技术 。它使得系统中为有限物理内存竞争的进程所需内存空间得到满足 。

虚拟内存技术不仅仅可让我们可以使用更多的内存,它还提供了以下功能:

巨大的寻址空间

操作系统让系统看上去有比实际内存大得多的内存空间 。虚拟内存可以是系统中实际物理空间的许多倍 。每个进程运行在其独立的虚拟地址空间中 。这些虚拟空间相互之间都完全隔离开来,所以进程间不会互相影响 。同时,硬件虚拟内存机构可以将内存的某些区域设置成不可写 。这样可以保护代码与数据不会受恶意程序的干扰 。

内存映射

内存映射技术可以将映象文件和数据文件直接映射到进程的地址空间 。在内存映射中,文件的内容被直接连接到进程虚拟地址空间上 。

公平的物理内存分配

内存管理子系统允许系统中每个运行的进程公平地共享系统中的物理内存 。

共享虚拟内存

尽管虚拟内存允许进程有其独立的虚拟地址空间,但有时也需要在进程之间共享内存 。例如有可能系统中有几个进程同时运行BASH命令外壳程序 。为了避免在每个进程的虚拟内存空间内都存在BASH程序的拷贝,较好的解决办法是系统物理内存中只存在一份BASH的拷贝并在多个进程间共享 。动态库则是另外一种进程间共享执行代码的方式 。共享内存可用来作为进程间通讯(IPC)的手段,多个进程通过共享内存来交换信息 。Linux支持SYSTEM V的共享内存IPC机制 。

3.1 虚拟内存的抽象模型



图3.1 虚拟地址到物理地址映射的抽象模型


在讨论Linux是如何具体实现对虚拟内存的支持前,有必要看一下更简单的抽象模型 。

在处理器执行程序时需要将其从内存中读出再进行指令解码 。在指令解码之前它必须向内存中某个位置取出或者存入某个值 。然后执行此指令并指向程序中下一条指令 。在此过程中处理器必须频繁访问内存,要么取指取数,要么存储数据 。

虚拟内存系统中的所有地址都是虚拟地址而不是物理地址 。通过操作系统所维护的一系列表格由处理器实现由虚拟地址到物理地址的转换 。

为了使转换更加简单,虚拟内存与物理内存都以页面来组织 。不同系统中页面的大小可以相同,也可以不同,这样将带来管理的不便 。Alpha AXP处理器上运行的Linux页面大小为8KB,而Intel X86系统上使用4KB页面 。每个页面通过一个叫页面框号的数字来标示(PFN)。

页面模式下的虚拟地址由两部分构成:页面框号和页面内偏移值 。如果页面大小为4KB,则虚拟地址的 11:0位表示虚拟地址偏移值,12位以上表示虚拟页面框号 。处理器处理虚拟地址时必须完成地址分离工作 。在页表的帮助下,它将虚拟页面框号转换成物理页面框号,然后访问物理页面中相应偏移处 。

图3.1给出了两个进程X和Y的虚拟地址空间,它们拥有各自的页表 。这些页表将各个进程的虚拟页面映射到内存中的物理页面 。在图中,进程X的虚拟页面框号0被映射到了物理页面框号4 。理论上每个页表入口应包含以下内容:


有效标记,表示此页表入口是有效的
页表入口描叙的物理页面框号
访问控制信息 。用来描叙此页可以进行哪些操作,是否可写?是否包含执行代码?
虚拟页面框号是为页表中的偏移 。虚拟页面框号5对应表中的第6个单元(0是第一个) 。

推荐阅读