内存管理之虚拟页式分配

       分页内存分配和分段内存分配可以解决程序在内存中离散存放的问题,但是,这个两种方式都要求程序将整个装入内存。如果程序比内存大,那么分页和分段都无法解决这个问题。其实一个程序在短时间内的执行可能局限于某小段程序范围内,这样把程序全部调入内存早成空间浪费,可以只装入一部分,进程需要的其他数据存放在外存,当需要的时候调入内存。这样做的好处:内存中可以保存更多的进程;进程可以比主存大。

1.虚拟存储器

       虚拟存储是指请求调入功能和置换功能。给用户的感觉是整个进程被调入了内存,其实是只有一部分,其余部分在外村。虚存就是内存和外存之和。虚拟存储需要解决如下几个问题:

     (1)地址映射:一个页面可能多次被调入和调出内存,每次在内存的地址不同,这就需要将逻辑地址转换为相应的物理地址,并且是动态的。

     (2)分配策略:为了访问虚存中的任何部分,待访问的数据必须驻留在内存。事先要提供一个种存储器分配策略,以确定要调入的部分装入到存储器的哪个位置。

     (3)置换策略:当系统内存空间不够时,系统必须通过换出页面来找到空间。系统可以将进程某些不用的空间换出内存,也可以将其他进程页面换出,如何取舍。

     (4)装载控制:静态装载将进程的所有虚拟存储器装载到内存。动态装载只是用的时候才装入。

2.请求分页

       请求分页存储管理方式也叫虚拟页式分配,是虚拟器存储器的一种实现方法。所谓请求分页是指在基本分页上的基础上增加请求调页和页面置换功能的一种存储分配策略纯分页系统中,进程的所有页面都在物理内存中,而虚拟页式分配,一个进程只有部分页在内存中,一部分在外存中。一旦进程访问的页不在内存,对进程来说就意味着缺页,就通过缺页中断向操作系统发出一个请求,请求把内存中位于外存的页调入内存。

     请求分页的硬件支持:页表需要加入几个标志项,缺页中断机构和地址变换机构。

      内存分配策略:分配给一个进程的存储量越小,内存中容纳的进程数越多,但是进程缺页异常也就越频繁。同时给进程分配一定数量的物理块后,由于局部原理,给该进程分配更多的页物理块对该进程的缺页率无影响了。三种分配策略:

     (1)固定分配策略:分配给进程的物理块在运行过程中不变,当进程发生缺页时,从该进程中占用的几个物理块找到一页替换出去。

     (2)可变局部分配策略:内存中每个进程分配了一定数量的物理块。但是系统中还有一个空闲物理块。进程发生缺页时,先检查空闲物理块,如果有空的,直接分配给进程。没有空的,只能从进程自己的空间中选一页置换出去。

     (3)可变分配全局置换:一旦进程发生缺页,从整个内存中选择一页置换出去。

       在采用固定分配时,可以按照进程数平均分配给每个进程等份的空间;可以按照进程大小比例分配空间;考虑进程优先级分配。

3.页面转换算法

      当页不在内存中,系统要选一页移到外存中,下面介绍几个固定分配局部置换的内存分配策略:

     (1)最优页面置换算法(OPT):缺页时,当前内存中的这几页中,有的页再也不用了,那么把该页置换出是最好的。如果当前内存中的几页都要使用,选择一个最后用到的页把他转换出去。

范例:内存为某进程分配三个物理块(不能变了),进程页面走向如下:7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

        7:发生缺页中断,调入内存;  0:发生缺页中断,调入内存;1:发生缺页中断,调入内存;2:需要从7,0,1中选择一个置换,页面7是第18个要访问的页面,0是第5个要访问的页面,1是第14个访问的页面,所以选择7置换,即内存总还剩2 0 1。依次类推。。。

注意:开始内存是空的,所以没有页面,这时也算缺页异常。

      (2)先进先出算法:总是选择当前系统中最早进入内存的那一页置换出去。

范例:内存为某进程分配三个物理块(不能变了),进程页面走向如下:7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

       7:发生缺页中断,调入内存;  0:发生缺页中断,调入内存;1:发生缺页中断,调入内存;2:淘汰7,即内存中0 1 2;2:已经在内存;0:在内存;3:0是最早进入内存的,虽然前一次是0,但是因为内存中,已经有了所以不算新进入的。后面依次了退。。

        FIFO算法有时候会产生Belady现象,即分配给进程空间增大,反而缺页率增加了,其他算法没有。

     (3)最近很少使用置换算法(LRU):总是选择当前页面中没有被使用时间最久的那一页,即使用最少的那一页,将它换出出去。

范例:内存为某进程分配三个物理块(不能变了),进程页面走向如下:7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1

最终的序列:(7 0 1)(2 1 0)(0 2 1)(3 0 2)(0 3 2)(4 0 3)(2 4 0)(3 2 4)(0 3 2)(3 0 2)。。。

     (4)clock算法:针对FIFO性能差,而LRU实现困难。Clock算法需要给每个物理块增加一个附加位,称为使用位。当某页装入内存时,使用位设为1,物理块被使用时,也被设为1。clock算法将页面看作一个循环缓冲区,并且有一个指针与之关联。当需要进行置换的时候,指针扫描,如果指针所指的页面为0,则被置换。如果不为0,将其置0,继续扫描下一块,直到找到一个使用位为0的块。如果所有位都是1,则扫描整个系统,回到指针开始的位置替换该页。所有的使用位为0,则指针指向的物理块被替换。

       Unix的clock算法:unix不是在缺页的时候才选择置换,而是一次缺页总是使用当前空闲物理块表中的一块,如果没有空闲块,则进程会被阻塞,直到有空闲块。unix中有一个页面守护进程周期性醒来,然后选择一些使用位为0的页面置换出去。

     (5)改进时钟算法:时钟算法只考虑了每一页的使用频率,并没有考虑该页是否被修改。如果系统中的某一页被换出,而且它被修改了,那么需要把该页重新写回外村(没有被修改的时候,不要写到外存,直接替换)。为了区分是否被修改,额外添加一个修改位w。新页面装入内存时,w=0,修改后,w=1。具有两个附加位的物理块中的页具有以下四种情况:

              a.最近未被访问过,未被修改过(u=0,w=0);//最适合换出的页面

              b.最近未被访问过,被修改过(u=0,w=1);//上面的没有选择这种页面

              c.最近被访问过,未被修改过(u=1,w=0);//上面的没有选择这种页面

              c.最近被访问过,被修改过(u=1,w=1);//上面的没有选择这种页面


原文地址:https://www.cnblogs.com/dyllove98/p/3138882.html