linux操作系统再内存不足时会使用Swap机制,将一些不经常使用的匿名内存页放到磁盘当中,等下次需要时再读取到内存当中,而这个LRU算法就是用来选择把哪些不常使用的匿名内存页放到磁盘当中的。
LRU(Least Recently Used)
:最近最少使用。其原理就是:当内存不足时,淘汰系统中最少使用的内存,这样对系统性能的损耗是最小的。
为了实现LRU算法,内核维护了两个双向链表:active_list 和 inactive_list。下面介绍下这两个链表的作用:
- active_list:活跃内存页链表。也就是说进程会经常访问这个链表中的内存页,所以进行内存淘汰时,不应该淘汰这个链表中的内存页。
- inactive_list:不活跃内存页链表。也就是说进程很少会访问这个链表中的内存页,所以进行内存淘汰时,淘汰这个链表中的内存页。
这链表中每个节点还有一个数值“PG_referenced”,这个数值再第二次机会法中使用,给这个内存页第二次机会。
被访问时各个情况分析:
1、当某个进程申请一个匿名内存页时:
内核会将这个内存页添加到active_list链表中,并将PG_referenced标志设置为0。
2、当某个再active_list链表的内存页被访问时:
会将此内存页的PG_referenced值变为1.
3、当某个再inactive_list链表且PG_referenced为0的内存页被访问时:
会将此内存页的PG_referenced值变为1.
4、当某个处于inactive_list链表中,且PG_referenced为1的内存页被访问时:
会将此链表移动到活跃链表,并且将PG_referenced置为0.
内存淘汰时,只能从inactive_list中进行淘汰,淘汰过程如下:
- 从inactive_list 的尾部开始进行内存淘汰,如果内存页的
PG_referenced
标志位为 1 时,将跳过此内存页,并且将此内存页的PG_referenced
标志位设置为 0。 - 如果内存页的
PG_referenced
标志位为 0 时,那么将此内存页写入到磁盘当中,并且将所有与此内存页的映射解除绑定,然后释放此内存页。 - 再淘汰的过程中active_list链表中的内存页也要进行衰退,扫描active_list链表,当其
PG_referenced
值为1时将其置为0,当值为0时,要将其从active_list链表移到inactive_list链表中。