Linux 物理页面的周转

来源:互联网 发布:autodesk 设计造型软件 编辑:程序博客网 时间:2024/04/20 08:06

在前几篇博文我们频繁提到了物理页面,swap交换分区。那么,在这一篇博文,我们将详细探索物理页面。

 

物理页面的周转

 

物理页面的周转有两层意思,一层是盘区交换。第二层是页面的换入换出。

 

下面来谈谈盘区交换

首先,不是所有的物理页面都能被交换的,比如系统空间的页面就不会被交换掉(交换掉了就没人干活了)。页面的交换比较复杂,我们一共能想到这几种思路。

1、最简单的很明显,不够了我就换。每当缺页异常的时候就分配一个页面,如果没有空闲的页面分配,就把一个或几个页面换进磁盘里,腾出几个页面出来。

2、积极一点的方法就是定期的,最好是在系统相对空闲的时候挑出一些页面预先换出,未雨绸缪。挑选的准则就用LRU(最近最少用到)。但是也有个毛病,就是如果我刚换了一个最近没用到的,接着就收到了一个访问请求。那就白搭了。

3、2的基础上再改改,比如把页面换出和页面的释放分为两步操作。我准备换的时候就把页面内容写进磁盘里,但是我占据的页面却不释放,反而放进一个缓存队列里。如果再过一段时间没有收到访问请求,我再释放掉。

再把3拿来改改,如果我准备换出的页面是干净的,没被修改过的,那么我就不用写进磁盘里。如果这个页面是脏的,被修改过的,我也不用立即写进去,断开映射就好了,过一段时间没有被访问修改我再写进去。

 

物理页面的换出

 

为了避免在缺页异常的时候再来搜索可供换出的页面再来换出,linux会定期检查并且预先换出若干页面。这个东西叫kswapd

 

kswapd从原理上来说是一个进程,有着自己的task_struct,受内核调度。正是如此,所以就可以让它在系统相对空闲的时候来运行。不过,与普通进程的不同是,没有独立的地址空间。所以这更像是一个线程。kswapd用内核的空间,他的代码是静态链接在内核的,可以直接调用内核的子程序。

 

kswapd会在初始化之后无限循环,每次循环会进入睡眠。在一定时间后会被唤醒,再次循环,再次睡眠。每次循环会做两件事。一件是例行的,会吧不活跃的脏页面写进交换区;一件是非例行的,在发现物理页面不够的时候会执行,找到若干页面断开映射。

 

每次循环还会做这么一个检查,检查缓存队列里页面的情况。缓存队列有两个,一个是放着不活跃的脏页面的,一个是放着不活跃的干净页面的。主要检查的是脏页面的。

 

一些页面虽然进入了不活跃的脏页面队列,但是有时候情况会发生变化,需要回到活跃的页面队列里。一些页面被锁住了,正在被操作,这时应该把这个页面放到队列的末尾。如果这个页面在收到进程用户空间映射的时候同时被用内存空间来模拟磁盘,这种情况也不应该被放进交换区里。如果这个页面被洗干净了,那么就应该放回不活跃的干净页面里。

 

 

物理页面的换入

 

如果一个线性地址与物理地址的映射已经建立,但是发现相应的页目录或者页表项的present位为0,那就代表着相应物理页面不在内存,会造成页面异常。

 

因为缺页造成的页面异常的处理如下:

1、首先看看相应的内存界面是否还在缓存队列里没有释放,如果是的话就很简单了,恢复映射就好

2、如果没有找到,也就是说这个内存页面已经释放,那就要重新分配一个内存页面。在读的时候,如果每次仅仅读一个页面是不经济的,因为每次读盘都要经过在磁盘上寻道使磁头定位,寻道所需的时间比磁头到位后读一个页面的时间要长。所以会以此多读几个页面,形成页面集群。预读进来的页面暂时链入活跃页面队列里。如果预读的时候因为分配不到足够的页面导致预读失败,那就得再读一次,这次就只读一个页面了。