LRU算法

本文深入探讨了Linux内核中LRU算法的实现,包括主要数据结构、页面在LRU链表中的移动以及页面在LRU链表中的分类。重点介绍了X86平台上的LRU算法特点和页面管理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,实现LRU的主要数据结构

  内核使用LRU算法对物理页面进行回收,即内核总是试图将最久没有被使用的老页面回收到伙伴系统。X86上Linux对LRU算法的实现貌似比较粗糙,页面的“新旧”程度仅被分为四个等级,内核使用两条链来组织相关物理页面:

      active_list代表活跃页面链表,inactive_list代表非活跃页面链表。页面通过struct page结构中的lru成员链入这两条LRU链,当页面被链入时,置PG_lru标志;更进一步,当页面是被链入active_list的时候要置PG_active标志;此外还有一个PG_referenced标志,用于当页面被访问时设置。

  当页面最近被使用时会被移到active_list中,如果页面久未使用则会被移到inactive_list中去。回收时只会回收inactive_list中的页面。

二,页面在LRU链表中的移动

  首先明确哪些页面会在LRU链中出现。内核并不是把所有使用的物理页面都链入LRU中,而是只有某些使用量大易于回收的页面,总的来说有两大类页面会被链入LRU链中:

  1,用于进程地址空间映射的匿名页

  2,page cache页(包含swap cache和普通的page cache)

细分来讲,这两大类可分为很多不同的情况,一是进程映射的页且未加入swap cache;二是进程映射的页且加入了swap cache;三是进程映射的页且属于普通的page cache,即mmap的页面;四是仅仅为page cache,即进程未映射但页面属于普通的page cache或是swap cache。不管属于哪种情况,他们的共性是要么可以与磁盘I/O将页面洗干净,要么就是可以直接丢弃以达到回收的目的。

  在X86上,LRU中的页面由旧到新分为四个等级:

  1,属于inactive_list,没有设置PG_referenced。    [PG_lru]

      2,属于inactive_list,设置了PG_referenced。       [PG_lru|PG_referenced]

      3,属于active_list,没有设置PG_referenced。  [PG_lru|PG_active]

      4,属于active_list,设置了PG_referenced。   [PG_lru|PG_active|PG_referenced]

当页面被访问时调用mark_page_accessed(),执行的就是1->2->3->4的状态转换。内核在很多地方需要使用mark_page_accessed()来标志页面最近已被访问,将页面从“老”到“新”提升等级。如果说内核各执行路径纷纷将各自用过的页面往“新”的状态刷,那么显然就需要一个反对者将它们又改回“老”状态,不然页面个个都是新页面,页页都不能回收了。这个反对者就是内存的回收者,回收者的工作就是在LRU链中找出最老的页面进行回收,它只关注inactive_list,因为显然inactive_list中的比较老,然而在扫描inactive_list并进行回收之前,它要走一遍active_list,把active_list中相对较老的降级到inactive_list中,即完成状态4->3->2的降级,这是通过函数refill_inactive()实现,它有唯一调用点在shrink_caches()中shrink_cache()之前。

  最后要强调一点,了解LRU中链了哪些类型的页面是理解内存回收关键函数shrink_cache()的关键。

 

Linux kernel version: 2.4.22 for x86

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值