LRU算法
来源:互联网 发布:java 实现websocket 编辑:程序博客网 时间:2024/05/22 13:39
一,实现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
- LRU算法
- LRU算法
- LRU算法
- LRU算法
- LRU 算法
- LRU算法
- LRU算法
- LRU算法
- LRU算法
- LRU算法
- lru算法
- LRU 算法
- LRU算法
- LRU算法
- Lru算法
- LRU算法
- LRU算法
- LRU算法
- N层架构的一些评论
- java实现单链表
- Flex获取操作XML示例
- bitmap on ldpi mdpi hdpi nodpi
- php农历算法(转)
- LRU算法
- .net過度效果
- 扩展spring jdbcTemplate 实现分页查询 转
- Managing an Agile Software Project
- 有关视频的异常
- SQL语句 SELECT LIKE 用法详解
- Nhibernate 之 二级缓存
- 获取IP
- android 包