linux内核异步内存回收的另一个思路:基于冷热文件的冷热区域精准的回收冷文件页( 四 )


每个文件对应一个结构,本方案定义了一个 全局结构体,把普通文件、大文件、热文件组织起来,如下:
为了叙述方便,下文把 结构体的、 、链表简称为 、 、 链表 。下一节开始介绍文件和内存page单元的关系 。
3.2.1 和的关系
如图,结构体有各种各样的链表、、、、,分别保存不同属性的 。
文件的链表:默认添加到链表 。异步内存回收线程只会遍历链表上!如图该文件的文件页page8~、~对应的内存page单元、就是在链表 。文件的链表:如果对应的文件页page被频繁访问,被判定是热,于是把该热移动到链表 。异步内存回收线程在较长一段时间都不会遍历链表上的,因为这些最近大概率还会被访问 。如图该文件的文件页page0~page3、~因为频繁访问,则把对应的内存page单元、移动到链表 。文件的链表:如果对应的文件页page被内存回收后,短时间又被访问,则被判定是。
于是把该移动到 链表,这些在较长一段时间不会再参与内存回收,即便age与全局相差较大!如图该文件的文件页~在内存回收后,短时间内这几个索引的page又被访问了,发生现象,于是把~对应的内存page单元移动到链表 。文件的链表:内存回收时,把链表尾的冷移动到链表 。内存回收时正是遍历每个文件的链表上的对应的文件页page 。如图,~、page4~page7 正在被内存回收,对应的内存page单元、正是在链表 。文件的链表:内存回收后的要从链表移动到链表,如果该对应的文件页page还是长时间不被访问则释放掉结构 。如果又被访问了则要把移动回链表 。如图~在内存回收后,对应的则被移动到链表 。
下文为了叙述方便,把文件的链表下文简称->,下文简称->,下文简称->,下文简称->,下文简称-> 。
3.2.3 的冷热判断
前文多次提到热,也就是频繁访问的,反应到代码层面是怎么界定的?先看下结构体的主要成员,主要有两个:
就是的age 。异步内存回收周期默认1分钟,每过一个周期令全局age加1,当对应的文件页page被访问,则把全局age赋值给的成员 。因此,的age就是最近一次被访问时的全局age 。的age与全局age差值越小,说明对应的文件页page最近被访问过;的age与全局age差值很大,说明这个对应的文件页page很长时间没有被访问了(冷) 。内存回收时正是优先遍历冷对应的文件页page(这些page是冷page) 。
是在一个周期的访问计数,对应的文件页page每访问一次则加1 。如果一个周期内对应的文件页page被访问的总次数大于阀值,被判定为热,则把该移动到该文件的->链表 。异步内存回收线程在较长一段时间都不会遍历->链表上的,因为这些最近大概率还会被访问 。
的age和都与的冷热有关系,但用途不一样 。在一个内存回收周期内,如果的大于阀值,则立即判定该是热的,然后移动到->链表,禁止一段时间内被异步内存回收线程遍历到 。的age表示广义的冷热程度,如果异步内存回收线程遍历到某个的较小,但是的age与全局age差值较小,也被判定是热,这种不参与内存回收,只是热的程度比不上很大的 。
好的,文件及内存page单元的组织关系已经介绍过了 。下文举个例子,介绍下一个文件的文件页page()的回收过程 。
3.3 异步内存回收举例
假设有个进程访问test文件,下文演示下怎么识别出哪些文件页page是频繁访问的,哪些是不经常访问,简单说就是识别出冷热文件页page,然后只回收冷文件页page 。注意,这个演示与实际代码实现有差异,为了演示方便简化了很多 。
在第1个内存回收周期,全部读取98304大小test文件 。于是先为该文件创建一个结构并添加到 链表 。接着为该文件的98304大小的分配6个内存page单元~ 。表示索引是0~3的文件页page0~page3,其他类推 。~最初添加到该文件->链表 。如下图: