页回收机制(一)

页回收机制(一)

当我们申请分配页的时候,页分配器首先尝试使用低水线分配页。如果使用低水线分配失败,说明内存轻微不足,页分配器将会唤醒内存节点的页回收内核线程,异步回收页,然后尝试使用最低水线分配页。如果使用最低水线分配失败,说明内存严重不足,页分配器会直接回收。
针对不同的物理页,采用不同的回收策略:交换支持的页和存储设备支持的文件页。

1.根据什么原则选择回收物理页

Linux内核使用LRU(Least Recently Used,最近最少使用)算法选择最近最少使用的物理页。
回收物理页的时候,如果物理页被映射到进程的虚拟地址空间,那么需要从页表中删除虚拟页到物理页的映射。

2.LRU(最近最少使用)链表

页回收算法使用LRU算法选择回收的页。每个内存节点的pglist_data实例就有一个成员lruvec,称为LRU向量,LRU向量包含5条LRU链表。
页回收机制(一)_第1张图片
在这里插入图片描述
struct lruvec结构定义如下:
页回收机制(一)_第2张图片
不活动匿名页LRU链表,用来链表不活动的匿名页,即最近访问频率低的匿名页;
活动匿名页LRU链表,用来链表活动的匿名页,即最近访问频率高的匿名页;
不活动文件页LRU链表,用来链表不活动的文件页,即最近访问频率低的文件页;
活动文件页LRU链表,用来链表活动的文件页,即最近访问频率高的文件页;
不可回收LRU链表,用来链接使用mlock锁定在内存中、不允许回收的物理页。

3.在LRU链表中,物理页的页描述符特征:

页描述符设置PG_lru标志位,表示物理页在LRU链表中;
页描述符通过成员lru加入LRU链表;
如果是交换支持的物理页,页描述符会设置PG_swapbacked标志位;
如果是活动的物理页,页描述符会设置PG_active标志位;
如果是不可回收的物理页,页描述符会设置PG_unevictable标志位。

每条LRU链表中的物理页按访问的时间从大到小排序,链表首部的物理页的访问时间离当前最近的,物理页从LRU链表首部加入,页回收算法从活动LRU链表的尾部取物理页回收,从活动LRU链表的尾部取物理页并且移动到不活动的LRU链表中。

4.LRU是双向链表,内核根据页面类型(匿名和文件)与活跃性(活跃不活跃),分为5种类型的LRU链表:

页回收机制(一)_第3张图片

5.如何确定页的活动程序?

如果是页表映射的匿名页或者文件页,根据页表项中的访问标志位确定页的活动程序。
如果没有页表映射的文件页,进程通过系统调用read或者write访问文件,文件系统在文件的页缓存中查找文件页,为文件页的页描述符设置访问标志位就可以。

6.反向映射

回收页表映射的匿名页或文件页时,需要从页表中删除映射,内核需要知道物理页被映射到哪些进程的虚拟地址空间,需要实现物理页到虚拟页的反向映射。

页描述符当中和反向映射具体成员如下:
页回收机制(一)_第4张图片

匿名页的反向映射视图如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
页回收机制(一)_第5张图片

7.匿名页的反向映射视图之间结构关系

页回收机制(一)_第6张图片
页回收机制(一)_第7张图片

8.发起页回收

申请分配页的时候,页分配器首先尝试使用低水线分配页,如果使用低水线分配失败,说明内存轻微不足,页分配器将会唤醒所有符合分配条件的内存节点的页回收线程,异步回收页,然后尝试使用最低水线分配页。如果分配失败,说明内存严重不足,页分配器将会直接回收页。如果直接回收页失败,那么判断是否应该重新尝试回收页。
页回收机制(一)_第8张图片
在这里插入图片描述
在这里插入图片描述
页回收机制(一)_第9张图片
页回收机制(一)_第10张图片
页回收机制(一)_第11张图片
页回收机制(一)_第12张图片
页回收机制(一)_第13张图片

9.直接回收

针对备用区域列表中符合分配条件的每个内存区域,调用函数shrink_node来回收内存区域所属的内存节点中的页。回收页是以内存节点为单位执行的,函数shrink_node负责回收内存节点中的页。

直接内存回收发生在慢速分配当中,首先唤醒所有的node节点的kswap内核线程,然后才会调用get_page_from_freelist()尝试用min阈值从zonelist的zone中获取连续页框,如果失败,对zonelist的zone进行异步压缩,异步压缩之后再次调用get_page_from_freelist()尝试用min阈值从zonelist的zone中获取连续页框,如果还是失败,就会进入到直接内存回收。
在进行直接内存回收时,晋城市有可能加入到node的pgdat->pfmemalloc_wait这个等待队列中,当kswap进行内存回收之后,如果node控股先内存达到平衡的状态,那么就会唤醒pgdat->pfmemalloc_wait中的进程。
其实也是加入到pgdat->pfmemalloc_wait这个等待队列进程,自身就不会进行直接内存回收,而是让kswapd进行,之后kswapd会唤醒它们即可。

_alloc_pages_direct_compact–>直接页面回收,然后进行页面分配
页回收机制(一)_第14张图片
页回收机制(一)_第15张图片
页回收机制(一)_第16张图片

你可能感兴趣的:(linux,学习,arm,c语言,数据结构)