浅析LRU算法及常用算法

场景:

用户信息存在于数据库里,但是由于我们对用户系统的性能要求比较高,显然不能每一次请求都去数据库。所以可以在内存中创建一个哈希表作为缓存,每次查找一个用户的时候现在哈希表中查询,以此提高性能。但是当用户数据超过一定的数值时,会发生内存溢出,造成服务器宕机。

解决方法:

LRU全称 Least Recently Used ,也就是最近最少使用的意思,是一种内存管理算法,最早应用于Linux操作西永。

LRU算法基于一种假设:长期不被使用的数据,在未来被用到的几率不大。因此,当数据所占内存达到一定阈值时,我们要移除掉最近最少被使用的数据。

在LRU算法中,使用了一种有趣的数据结构,这种数据结构叫做哈希链表。

什么是哈希链表呢?

我们都知道,哈希链表是由若干个Key-value所组成,在逻辑上,这些Key-Value是无所谓排列顺序的,谁先谁后都一样。

在哈希链表中,这些Key-Value不再是彼此无关的存在,而是被一个链条串了起来,每一个Key-Value都具有它的前驱Key-Value、后继Key-Value,就像双向链表中的节点一样。这样一来,原本无序的哈希表拥有了固定的排列顺序。

依靠哈希链表的有序性,我们可以把Key-Value按照最后的使用时间来排序。

示例代码:

private  Node head;
private  Node end;
//缓存存储上限 
private  int limit;
private  HashMap<String, Node>  hashMap;
public  LRUCache(int limit){this.limit=limit;hashMap=new HashMap<String, Node>();}
public  String get(String key){Node node=hashMap.get(key);
        if(node==null){return null;}
        refreshNode(node);return node.value;}
public  void put(String key,String value){Node node=hashMap.get(key);
        if(node==null){
        //如果key不存在,插入key-value         
        if(hashMap.size()>=limit){String oldKey=removeNode(head);
        hashMap.remove(oldKey);}
        node=new Node(key,value);
        addNode(node);
        hashMap.put(key,node);}else{        //如果key存在,刷新key-value      
        node.value=value;refreshNode(node);}}
public  void remove(String key){
        Node node=hashMap.get(key);
        removeNode(node);
        hashMap.remove(key);}
/**
 * 刷新被访问的节点位置  * @param  node 被访问的节点
 */
private  void refreshNode(Node node){
        //如果访问的是尾节点,无需移动节点     if  (node ==  end )  {        return ;     }  
        //移除节点    
        removeNode(node);
//重新插入节点     addNode ( node ); }   
/**  * 删除节点  * @param  node 要删除的节点  */
private  String removeNode(Node node){
        if(node==end){
        //移除尾节点       
        end=end.pre;}else if(node==head){
        //移除头节点         head = head . next ;     } else  {      
        //移除中间节点         node . pre . next  = node . next ;         node . next . pre = node . pre ;     }   
        return node.key;}
/**  * 尾部插入节点  * @param  node 要插入的节点  */
private  void addNode(Node node){
        if(end!=null){
        end.next=node;
        node.pre=end;
        node.next=null;}
        end=node;
        if(head==null){
        head=node;
        }}

class Node {
    Node(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public Node pre;
    public Node next;
    public String key;
    public String value;
}

以上例代码非线程安全,如有需求,需要加上synchronized修饰符

对于刚才这种类似的需求也可以使用缓存数据库redis来实现,Redis底层也实现了类似于LRU的回收算法。

FIFO算法:

先进先出算法:即FIFO,通过缓存中的块进入队列的先后顺序进行淘汰和替换,先进入缓存的数据块最先被替换。

随机替换算法:

随机替换算法:顾名思义,就是通过随机获得一个需要被替换的块号,并用新的数据替换该块。

LFU算法:

最不经常使用算法:即LFU,这个算法需要记录每一个缓存块被访问的频率,每一次替换都从最低访问频率的数据块开始。

MRU算法:

最近最常使用算法,即MRU,这个算法会最先移除最近最常使用的数据块。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 如果内容只被占用,势必会导致内存撑爆,导致缓慢,甚至宕机,因此就需要淘汰算法来淘汰低频度使用的数据,释放内存。在R...
    吕艳凯阅读 555评论 0 0
  • LRU算法介绍 众所周知,操作系统缓存是有限的,当缓存快要耗尽的时候,我们就需要对已经存在的页面进行置换。记得在大...
    李连毛阅读 1,135评论 0 2
  • 缓存是一个计算机思维,对于重复的计算,缓存其结果,下次再算这个任务的时候,不去真正的计算,而是直接返回结果,能加快...
    ck2016阅读 26,520评论 0 17
  • 内容来源:网上找的,并非原创,原链接找不到了!特此说明!! 排序 比较排序 冒泡排序 重复地走访过要排序的数列,每...
    sunjiandev阅读 274评论 0 0
  • 5月以来,哪怕对市场风向再不敏感的人,也感觉到阵阵凉意。二级市场连续下挫,一级市场融资环境恶化,不论企业融资数量还...
    钱皓频道阅读 6,018评论 1 6