缓存 是我们写代码过程中常用的一种手段,是一种空间换时间的做法。就拿我们经常使用的 HTTP 协议,其中也存在强缓存和协商缓存两种缓存方式。当我们打开一个网站的时候,浏览器会查询该请求的响应头,通过判断响应头中是否有 Cache-Control、Last-Modified、ETag 等字段,来确定是否直接使用之前下载的资源缓存,而不是重新从服务器进行下载。
下面就是当我们访问百度时,某些资源命中了协商缓存,服务端返回 304 状态码,还有一部分资源命中了强缓存,直接读取了本地缓存。

但是,缓存并不是无限制的,会有大小的限制。无论是我们的 cookie(不同浏览器有所区别,一般在 4KB 左右),还是 localStorage(和 cookie 一样,不同浏览器有所区别,有些浏览器为 5MB,有些浏览器为 10MB),都会有大小限制。
这个时候就需要涉及到一种算法,需要将超出大小限制的缓存进行淘汰,一般的规则是淘汰掉最近没有被访问到的缓存,也就是今天要介绍的主角:LRU (Least recently used:最近最少使用)。当然除了 LRU,常见的缓存淘汰还有 FIFO(first-in, first-out:先进先出) 和 LFU(Least frequently used:最少使用)。
什么是 LRU?
LRU (Least recently used:最近最少使用)算法在缓存写满的时候,会根据所有数据的访问记录,淘汰掉未来被访问几率最低的数据。也就是说该算法认为,最近被访问过的数据,在将来被访问的几率最大。
为了方便理解 LRU 算法的全流程,画了一个简单的图:

1.假设我们有一块内存,一共能够存储 5 数据块;
2.依次向内存存入A、B、C、D、E,此时内存已经存满;
3.再次插入新的数据时,会将在内存存放时间最久的数据A淘汰掉;
4.当我们在外部再次读取数据B时,已经处于末尾的B会被标记为活跃状态,提到头部,数据C就变成了存放时间最久的数据;
5.再次插入新的数据G,存放时间最久的数据C就会被淘汰掉;