[操作系统] 分页系统的设计问题

来源:互联网 发布:网站cms系统 编辑:程序博客网 时间:2024/06/01 16:31

分页系统的设计问题


  • 分页系统的设计问题
    • 局部策略与全局分配策略
    • 负载控制
    • 页面大小
    • 分离的指令空间和数据空间
    • 共享页面
    • 共享库
    • 内存映射文件
    • 清除策略
    • 虚拟内存接口


1. 局部策略与全局分配策略

假如三个进程A,B为当前可运行进程。假如A发生了缺页中断,页面置换算法在置换页面时,如果只考虑已经分配给A的页面,就叫做局部页面置换算法。而如果置换的页面不考虑被置换的页面属于哪个进程,则叫做全局页面置换算法。

局部算法可以有效地为每个进程分配固定的内存片段。全局算法在可运行进程之间动态地分配页框,因此分配给各个进程的页框数也是随时间变化的。

全局算法在通常情况下比局部算法要好。但是工作集算法和WSClock算法只在局部策略中才有意义,因为没有针对整个机器的工作集。所以在必须使用局部策略时,可以按进程大小按比例分配页面数量,但是为了保证进程可以运行,需要给规定一个最小页框数。即使某个进程达不到这个比例,也应该分配给它规定的最小页框数

2. 负载控制

一旦所有进程的组合工作集超出了内存容量就有可能发生颠簸。因为一旦有进程需要更多的内存,但是没有进程需要更少的内存,只能暂时从内存中去掉一些进程。可行的方法是将一部分进程交换到磁盘,并释放所有它们所占有的页面。如果颠簸依然没有停止,则需要交换出更多进程,直到颠簸结束。

另外,如果交换出过多的进程,CPU可能长时间处于空闲状态,所以在交换进程时,还应该考虑进程的特性(计算密集型还是I/O密集型)。

3. 页面大小

页面大小的选择没有最优选择,大页面和小页面各有优点何缺点。

小页面优点:

  • 正文段、数据段和堆栈段一般情况下无法恰好装满整个页面,平均情况下最后一个页面的一半是空的。这些浪费的空间叫做内部碎片。所以页面越小,浪费的字节就越小(当内存中有n个段、页面大小为p字节时,浪费的碎片为np/2字节)。

  • 如果一个程序是按阶段顺序执行的,每阶段需要的内存很小,如4KB,如果页面大小是32KB,那么每次会浪费很多空间。

小页面缺点:

  • 小页面需要更多页面,即需要更大的页表。内存与磁盘的传输一般为一次一页,这就意味着需要更多的传输。大部分时间用在了磁盘的寻道和延迟上,传输一个小页面和大页面本身的时间可以被忽略了。所以更多次的传输意味着更多的时间。
  • 某些机器中,每次进程切换都必须要装入页表,小页面也会花费更多时间。

4. 分离的指令空间和数据空间

大多数计算机只存在一个地址空间,既存放程序也存放数据。可以将指令(程序正文)和数据分离,放在两个不同的地址空间,这样两个空间都可以进行分页,并且相互独立。这种方法可以使可用的地址空间加倍,所需要的仅仅是当硬件取指时告诉它使用哪个空间。另外将指令与数据分离,对下面提到的共享页面来说会变的很简单。

5. 共享页面

当几个不同的用户同时运行同一个程序时。为了避免在内存中有一个页面的两份副本,使用共享页面效率更高。只读页面(如程序文本)可以共享,但是数据页面不能共享。

如果支持指令空间和数据空间的分离,那么可以在每个进程的进程表中添加两个指针,一个指向指令空间,一个指向数据空间。如果进程A,B运行的是同一个程序,那么它们指向指令空间的指针可以指向同一个页。

共享页面

存在的问题是,假设进程A和B同时运行一个编辑器并共享页面。如果调度程序决定从内存中移走A,并撤销A所有的页面,那么这会造成B大大量的缺页中断需要把共享页面重新调入。所以,当A结束时,能够发现共享页面仍在被使用是很重要的。可以使用一个专门的数据结构进行记录。

如果想要对数据空间进行共享,可以让每个进程有自己单独的页表,但是同时指向一个数据页面集合。当这些进程只是读数据而不做更改时,可以一直使用。如果作出更改,操作系统就会生成一个该页的副本,这个进程就有自己的副本了。该方法被称为写时复制,通过减少那些不执行写操作的页面的复制而提高了性能。

6. 共享库

如果一个程序装载了某个共享库(如一些函数等),其他的程序就没有必要再次装载这个库了。并且一个共享库被装载和使用时,不是一次性被读入内存的,而是根据需要,以页面为单位装载的。共享库的另一个优点是,如果里面的一个函数被修改了,不需要重新编译程序,旧的文件依然可以正常工作通过使用新的共享库来替换原有文件,就可以使用新的共享库了。

共享库所造成的问题是重定位问题,如图

共享库

如进程1,2共享一个20KB的库(每个框为4KB)。在进程1中,这个库被定位在36K+16,但是在进程2中,如果将36K+16作为地址装载就会出错,因为需要跳转的地址是12K+16。

所以,在编译共享库时,需要用特殊的编译选项告诉编译器,不要产生使用绝对地址的指令,只产生使用相对地址的指令,不管共享库被放在虚拟空间的什么位置,都可以正确工作。这种只使用相对偏移量的代码叫做位置无关代码。

7. 内存映射文件

共享库实际为该机制的特例。核心思想是:进程可以通过发起一个系统调用,将一个文件映射到其虚拟地址空间的一部分。在多数实现中,在映射共享的页面时不会实际读入页面内容,而是在访问页面时才会读入。当进程退出或显式地解除文件映射时,所有被改动的页面会被写回到文件中。

这个机制可以把一个文件当做一个内存中的大字符数组来访问,而不用通过读写操作来访问文件。如果两个或以上进程同时映射了同一个文件,他们就可以通过共享内存来通信。

8. 清除策略

发生缺页中断时如果系统中有大量的空闲页框,此时的分页系统在最佳状态。所以应该建立一个叫做分页守护的后台进程,它在多数时候睡眠,但会被定期唤醒,如果空闲页框过少,分页守护进程通过预定的页面置换算法选择页面换出内存。如果这些页面被修改过则将他们写回磁盘。

在任何情况下,页面中原先的内容都应该被记录在一个缓冲区中。当需要使用一个被淘汰的页面时,如果该页框没被覆盖,则可从这个缓冲区中移出并恢复该页面。分页守护进程,保证了所有空闲页框是干净的,所以空闲页框在被分配时不必着急写回磁盘。

实现方法是使用一个双指针时钟。前指针由分页守护进程控制。当它指向一个脏页面时,就写回磁盘,前指针向前移动,当指向干净页面时,不写回磁盘,只移动前指针。后指针用于页面置换,与标准时钟算法中的指针一样。

9. 虚拟内存接口

在一些高级系统中,程序员可以对内存映射进行控制。允许控制的原因是为了允许两个或多个进程共享一部分内存。实现共享内存的方法是对内存区域进行命名,通过让一个进程把内存区域的名字告诉第二个进程,使得第二个进程可以把该区域映射到第二个进程自己的虚拟地址空间中。这样一个进程可以往共享内存中进行写内容,另一个进程读内容,就可以进行高速的通信。

页面共享可以用来实现高性能的消息传递系统,因为普通情况下传递消息,数据被从一个地址空间复制到另一个地址空间开销很大。而如果可以空着页面映射,发送方可以清除那些包含消息的页面的映射,接收进程映射进来,这种方法只需要复制页面名字,而不用复制数据本身。

参考书目:现代操作系统第三版

原创粉丝点击