日期:2014-05-16  浏览次数:20623 次

Linux内核中的内存(三)
版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127

 

页高速缓存(cache)Linux内核实现磁盘缓存,通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理内存的访问。页回写是将页高速缓存中的变更数据刷新回磁盘的操作。引入磁盘高速缓存的目的主要有两个:其一,访问内存速度比访问磁盘快的多;其二,临时局部原理。

 

读后备存储(正被缓存的存储设备):首先检查需要的数据是否在页高速缓存中,如果在,则放弃访问磁盘,而直接从内存中读取,这个行为叫做缓存命中。如果缓存未命中,那么内核必须调度块I/O操作,从磁盘读取数据,然后内核将读来的数据放入页缓存中,这样方便后期的缓存命中。

 

写缓存:方法一,不缓存,即直接将数据写到磁盘,不通过页高速缓存。方法二,写透缓存,即写操作自动更新内存缓存,同时也更新磁盘文件。方法三,回写,即后备存储不立即直接更新,由一个回写进程周期性将脏页链表中的页写回磁盘,这样通过延迟写磁盘,可以方便在以后的时间内合并更多的数据和再一次刷新。

 

缓存回收,即缓存中的什么内容将被清除的策略。Linux的缓存回收是通过选择干净的页进行简单替换,难点在于什么页应该回收,理想的回收策略是预测算法,同时还有最近最少使用算法(LUR),双链策略(活跃链表和非活跃链表)

 

页高速缓存中的页可能包含多个不连续的物理磁盘块,Linux页高速缓存的目的是缓存任何基于页的对象,这包含各种类型的文件和各种类型的内存映射。Linux页高速缓存使用了一个新的对象管理缓存项和I/O操作,这个对象是struct address_space结构体,该结构体是虚拟地址struct vm_area_struct的物理地址对等体。一个被缓存的文件只和一个address_space结构体相关联,但它可以有多个vm_area_struct结构体,也就是物理页到虚拟页是个一对多的映射。我们对页高速缓存也有相应的操作函数,重点是wrutepagereadpage函数,读页时,如果在页高速缓存中未搜素到需要的页,则内核将从磁盘读入需要的页,然后将该页加入到页高速缓存,写页时,页高速缓存更像是一个存储平台,所有要被写出的页都要加入页高速缓存中。

 

基树

页高速缓存通过两个参数address_space对象加上一个偏移量进行搜索,每个address_space对象都有唯一的基树,它保存在address_space中的page_tree结构体中。基树是一个二叉树,只要指定文件偏移,就可以在基树中迅速检索到希望的页。

 

缓冲区高速缓存

独立磁盘块通过I/O缓冲也要被存入页高速缓存,这个缓冲就叫缓冲区高速缓存,实现上没有将它作为独立缓存,而是作为页高速缓存的一部分。在更早的内核中,有两个独立的磁盘缓存,即页高速缓存和缓冲区高速缓存,前者缓存页面,后者缓存缓冲区,今天我们只有一个磁盘缓存,即页高速缓存,但是内核仍然需要在内存中使用缓冲来表示磁盘块,多亏缓冲是用页映射块的,所以它正好在页高速缓存中。

 

脏页被回写发生在如下三种条件下:其一,当空闲内存低于一个特定阈值时;其二,当脏页在内存中驻留时间超过一个特定的阈值时;其三,当用户进程调用syns()fsync()系统调用时,内核会按要求执行回写动作。在2.6内核中,一群内核线程(flusher线程)执行回写,flusher线程会周期性地被唤醒并且把超过特定期限的脏页回写到磁盘,系统管理员可以到/proc/sys/vm中设置回写相关参数。除了常规的页回写flusher进程外,还有一种叫膝上型计算机模式,该策略主要是将硬盘转动的机械行为最小化,允许硬盘尽可能长时间地停滞,以延长电池供电时间,所以,机器可以在使用电池电源时自动既然怒膝上型计算机模式,而在插上交流电源时恢复到常规的页回写模式。