请你说一下虚拟内存置换的方式
参考回答:
比较常见的内存替换算法有:FIFO,LRU,LFU,LRU-K,2Q。1、FIFO(先进先出淘汰算法)
思想:最近刚访问的,将来访问的可能性比较大。
实现:使用一个队列,新加入的页面放入队尾,每次淘汰队首的页面,即最先进入的数据,最先被淘汰。
弊端:无法体现页面冷热信息
2、LFU(最不经常访问淘汰算法)
思想:如果数据过去被访问多次,那么将来被访问的频率也更高。
实现:每个数据块一个引用计数,所有数据块按照引用计数排序,具有相同引用计数的数据块则按照时间排序。每次淘汰队尾数据块。
开销:排序开销。
弊端:缓存颠簸。
3、LRU(最近最少使用替换算法)
思想:如果数据最近被访问过,那么将来被访问的几率也更高。
实现:使用一个栈,新页面或者命中的页面则将该页面移动到栈底,每次替换栈顶的缓存页面。
优点:LRU算法对热点数据命中率是很高的。
缺陷:
1)缓存颠簸,当缓存(1,2,3)满了,之后数据访问(0,3,2,1,0,3,2,1。。。)。
2)缓存污染,突然大量偶发性的数据访问,会让内存中存放大量冷数据。
4、LRU-K(LRU-2、LRU-3)
思想:最久未使用K次淘汰算法。
LRU-K中的K代表最近使用的次数,因此LRU可以认为是LRU-1。LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题,其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。
相比LRU,LRU-K需要多维护一个队列,用于记录所有缓存数据被访问的历史。只有当数据的访问次数达到K次的时候,才将数据放入缓存。当需要淘汰数据时,LRU-K会淘汰第K次访问时间距当前时间最大的数据。
实现:
1)数据第一次被访问,加入到访问历史列表;
2)如果数据在访问历史列表里后没有达到K次访问,则按照一定规则(FIFO,LRU)淘汰;
3)当访问历史队列中的数据访问次数达到K次后,将数据索引从历史队列删除,将数据移到缓存队列中,并缓存此数据,缓存队列重新按照时间排序;
4)缓存数据队列中被再次访问后,重新排序;
5)需要淘汰数据时,淘汰缓存队列中排在末尾的数据,即:淘汰“倒数第K次访问离现在最久”的数据。
针对问题:
LRU-K的主要目的是为了解决LRU算法“缓存污染”的问题,其核心思想是将“最近使用过1次”的判断标准扩展为“最近使用过K次”。
5、2Q
类似LRU-2。使用一个FIFO队列和一个LRU队列。
实现:
1)新访问的数据插入到FIFO队列;
2)如果数据在FIFO队列中一直没有被再次访问,则最终按照FIFO规则淘汰;
3)如果数据在FIFO队列中被再次访问,则将数据移到LRU队列头部;
4)如果数据在LRU队列再次被访问,则将数据移到LRU队列头部;
5)LRU队列淘汰末尾的数据。
针对问题:LRU的缓存污染
弊端:
当FIFO容量为2时,访问负载是:ABCABCABC会退化为FIFO,用不到LRU。