单风机HF-100S鸿冠 4寸管道风机洗手间/厨房/办公室吊顶静音风机 页面分配 Linux使用Buddy算法来有效的分配与回收页面块。页面分配代码每次分配包含一个或者多个物理页面的内存块。页面以2的次幂的内存块来分配。这意味着它可以分配1个、2个和4个页面的块。只要系统中有足够的空闲页面来满足这个要求(nr_free_pages > min_free_page), 内存分配代码将在free_area中寻找一个与请求大小相同的空闲块。free_area中的每个元素保存着一个反映这样大小的已分配与空闲页面 的位图。例如,free_area 数组中*二个元素指向一个反映大小为四个页面的内存块分配情况的内存映象。 分配算法首先搜寻满足请求大小的页面。它从free_area 数据结构的list域着手沿链来搜索空闲页面。如果没有这样请求大小的空闲页面,则它搜索两倍于请求大小的内存块。这个过程一直将持续到free_area 被搜索完或找到满足要求的内存块为止。如果找到的页面块大于请求的块则对其进行分割以使其大小与请求块匹配。由于块大小都是2的次幂所以分割过程十分简单。空闲块被连进相应的队列而这个页面块被分配给调用者。 图3.4 free_area 数据结构 在图3.4中,当系统中有大小为两个页面块的请求发出时,**个4页面大小的内存块(从页面框号4开始)将分成两个2页面大小的块。**个,从页面框号4开始的,将分配出去返回给请求者,而后一个,从页面框号6开始,将被添加到free_area数组中表示两个页面大小的空闲块的元素1中。 页面回收 将大的页面块打碎进行分配将增加系统中零碎空闲页面块的数目。页面回收代码在适当时机下要将这些页面结合起来形成单一大页面块。事实上页面块大小决定了页面重新组合的难易程度。 当页面块被释放时,代码将检查是否有相同大小的相邻或者buddy内存块存在。如果有,则将它们结合起来形成一个大小为原来两倍的新空闲块。每次结合完之后,代码还要检查是否可以继续合并成更大的页面。较佳情况是系统的空闲页面块将和允许分配的较大内存一样大。 在图3.4中,如果释放页面框号1,它将和空闲页面框号0结合作为大小为2个页面的空闲块排入free_area的**个元素中。 内存映射 映象执行时,可执行映象的内容将被调入进程虚拟地址空间中。可执行映象使用的共享库同样如此。然而 可执行文件实际上并没有调入 物理内存,而是仅仅连接到进程的虚拟内存。当程序的其他部分运行时引用到这部分时才把它们从 磁盘上调入内存。将映象连接到进程虚拟地址空间的过程称为内存映射。 图3.5 虚拟内存区域 每个进程的 虚拟内存用一个mm_struct来表示。它包含当前执行的映象(如BASH)以及指向vm_area_struct 的大量指针。每个vm_area_struct 数据结构描叙了 虚拟内存的起始与结束位置,进程对此内存区域的存取权限以及一组内存操作函数。这些函数都是Linux在操纵 虚拟内存区域时必须用到的 子程序。其中一个负责处理进程试图访问不在当前 物理内存中的 虚拟内存(通过页面失效)的情况。此函数叫nopage。它用在Linux试图将可执行映象的页面调入内存时。 可执行映象映射到进程 虚拟地址时将产生一组相应的vm_area_struct 数据结构。每个vm_area_struct 数据结构表示可执行映象的一部分: 可执行代码、初始化数据( 变量)、未初始化数据等等。Linux支持许多标准的 虚拟内存操作函数,创建vm_area_struct 数据结构时有一组相应的虚拟内存操作函数与之对应。 请求换页 当可执行映象到进程虚拟地址空间的映射完成后,它就可以开始运行了。由于只有很少部分的映象调入内存,所以很快就会发生对不在 物理内存中的 虚拟内存区域的访问。当进程访问无有效 页表入口的虚拟地址时,处理器将向Linux报告一个 页面错误。 页面错误带有失效发生的 虚拟地址及引发失效的访存方式。Linux必须找到表示此区域的vm_area_struct结构。对vm_area_struct 数据结构的搜寻速度决定了处理页面错误的效率,而所有vm_area_struct结构是通过一种AVL(Adelson-Velskii and Landis) 树结构连在一起的。如果无法找到vm_area_struct与此失效 虚拟地址的对应关系,则系统认为此进程访问了非法虚拟地址。这时Linux将向进程发送SIGSEGV信号,如果进程没有此信号的处理过程则终止运行。 如果找到此对应关系,Linux接下来检查引起该 页面错误的访存类型。如果进程以非法方式访问内存,比如对不可写区域进行写操作,系统将产生内存错误的信号。