Linux 核心--4.内存管理( 三 )



3.1.2 交换
如果进程需要把一个虚拟页面调入物理内存而正好系统中没有空闲的物理页面,操作系统必须丢弃位于物理内存中的某些页面来为之腾出空间 。

如果那些从物理内存中丢弃出来的页面来自于磁盘上的可执行文件或者数据文件,并且没有修改过则不需要保存那些页面 。当进程再次需要此页面时,直接从可执行文件或者数据文件中读出 。

但是如果页面被修改过,则操作系统必须保留页面的内容以备再次访问 。这种页面被称为dirty页面,当从内存中移出来时,它们必须保存在叫做交换文件的特殊文件中 。相对于处理器和物理内存的速度,访问交换文件的速度是非常缓慢的,操作系统必须在将这些dirty页面写入磁盘和将其继续保留在内存中做出选择 。

选择丢弃页面的算法经常需要判断哪些页面要丢弃或者交换,如果交换算法效率很低,则会发生"颠簸"现象 。在这种情况下,页面不断的被写入磁盘又从磁盘中读回来,这样一来操作系统就无法进行其他任何工作 。以图3.1为例,如果物理页面框号1被频繁使用,则页面丢弃算法将其作为交换到硬盘的侯选者是不恰当的 。一个进程当前经常使用的页面集合叫做工作集 。高效的交换策略能够确保所有进程的工作集保存在物理内存中 。

Linux使用最近最少使用(LRU)页面衰老算法来公平地选择将要从系统中抛弃的页面 。这种策略为系统中的每个页面设置一个年龄,它随页面访问次数而变化 。页面被访问的次数越多则页面年龄越年轻;相反则越衰老 。年龄较老的页面是待交换页面的最佳侯选者 。



3.1.3共享虚拟内存
虚拟内存让多个进程之间可以方便地共享内存 。所有的内存访问都是通过每个进程自身的页表进行 。对于两个共享同一物理页面的进程,在各自的页表中必须包含有指向这一物理页面框号的页表入口 。

图3.1中两个进程共享物理页面框号4 。对进程X来说其对应的虚拟页面框号为4而进程Y的为6 。这个有趣的现象说明:共享物理页面的进程对应此页面的虚拟内存位置可以不同 。



3.1.4物理与虚拟寻址模式
操作系统自身也运行在虚拟内存中的意义不大 。如果操作系统被迫维护自身的页表那将是一个令人恶心的方案 。多数通用处理器同时支持物理寻址和虚拟寻址模式 。物理寻址模式无需页表的参与且处理器不会进行任何地址转换 。Linux核心直接运行在物理地址空间上 。

Alpha AXP处理器没有特殊的物理寻址模式 。它将内存空间划分为几个区域并将其中两个指定为物理映射地址 。核心地址空间被称为KSEG地址空间,它位于地址0xfffffc0000000000以上区域 。为了执行位于KSEG的核心代码或访问那里的数据,代码必须在核心模式下执行 。Alpha上的Linux核心从地址0xfffffc0000310000开始执行.



3.1.5访问控制
页表入口包含了访问控制信息 。由于处理器已经将页表入口作为虚拟地址到物理地址的映射,那么可以很方便地使用访问控制信息来判断处理器是否在以其应有的方式来访问内存 。

诸多因素使得有必要严格控制对内存区域的访问 。有些内存,如包含执行代码的部分,显然应该是只读的,操作系统决不能允许进程对此区域的写操作 。相反包含数据的页面应该是可写的,但是去执行这段数据肯定将导致错误发生 。多数处理器至少有两种执行方式:核心态与用户态 。任何人都不会允许在用户态下执行核心代码或者在用户态下修改核心数据结构 。





图3.2 Alpha AXP页表入口


页表入口中的访问控制信息是处理器相关的;图3.2是Alpha AXP处理器的PTE(Page Table Entry) 。这些位域的含义如下:

推荐阅读