当前位置 博文首页 > A_art_xiang的博客:redis高级-内存淘汰策略

    A_art_xiang的博客:redis高级-内存淘汰策略

    作者:[db:作者] 时间:2021-07-13 21:46

    目录

    一、redis缓存过期淘汰策略

    1.redis默认内存

    2.修改redis内存

    3.查看redis内存情况

    二、redis内存超出了设置的最大值会怎么样

    1.设置1个字节之后再赋值,会爆OOM

    三、内存淘汰策略

    1.一个键过期了,是怎么删除的

    2.内存淘汰策略

    3.修改内存淘汰策略

    lru算法


    一、redis缓存过期淘汰策略

    1.redis默认内存

    ?? ?如果不设置最大内存大小或者设置最大内存大小为0,在64位操作系统下不限制内存大小,在32位操作系统下最多使用3GB内存

    ? ? 一般推荐redis设置内存为最大物理内存的四分之三

    2.修改redis内存

    ①修改配置文件

    ②通过命令

    3.查看redis内存情况

    二、redis内存超出了设置的最大值会怎么样

    1.设置1个字节之后再赋值,会爆OOM

    三、内存淘汰策略

    出厂默认:noeviction-报错OOM

    1.一个键过期了,是怎么删除的

    ①定时删除(对CPU不友好,用处理器性能换取存储空间)

    ②惰性删除(对内存不友好)

    ③定期删除(随机抽查,也会有漏网之鱼,会有一直没抽取到的)

    2.内存淘汰策略

    lru:删除最近最少使用的

    lfu:删除最少频繁使用的的。

    一般用第二个,allkeys-lru

    3.修改内存淘汰策略

    ①配置文件

    ②命令

    lru算法

    是什么:

    ? ? LRU是Least?Recently?Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的数据予以淘汰。

    1.面试题示例

    LRU算法核心是哈希链表

    使用LinkedHashMap实现LRU算法

    package 作业;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Scanner;
    import java.util.Set;
    
    
    
    
    /*LRU是Least Recently Used 近期最少使用算法。
    *通过HashLiekedMap实现LRU的算法的关键是,如果map里面的元素个数大于了缓存最大容量,则删除链表头元素
    */
    
    
    /*public LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder)
    *LRU参数参数:
    *initialCapacity - 初始容量。
    *loadFactor - 加载因子(需要是按该因子扩充容量)。
    *accessOrder - 排序模式( true) - 对于访问顺序(get一个元素后,这个元素被加到最后,使用了LRU  最近最少被使用的调度算法),对于插入顺序,则为 false,可以不断加入元素。
    */
    
    
    /*相关思路介绍:
      * 当有一个新的元素加入到链表里面时,程序会调用LinkedHahMap类中Entry的addEntry方法,
      *而该方法又会 会调用removeEldestEntry方法,这里就是实现LRU元素过期机制的地方,
      * 默认的情况下removeEldestEntry方法只返回false,表示可以一直表链表里面增加元素,在这个里  *修改一下就好了。
      *
      */
    /*
    测试数据:
    5
    11
    4 7 0 7 1 0 1 2 1 2 6
    */
    
    
    import java.util.*;
    public class LRULinkedHashMap<K,V> extends LinkedHashMap<K,V>{     
        private int capacity;                     //初始内存容量
        
        LRULinkedHashMap(int capacity){          //构造方法,传入一个参数
            super(16,0.75f,true);               //调用LinkedHashMap,传入参数   ,true是按照访问顺序,false是按照插入顺序排 
            this.capacity=capacity;             //传递指定的最大内存容量
        }
        @Override
        public boolean removeEldestEntry(Map.Entry<K, V> eldest){     
            //,每加入一个元素,就判断是size是否超过了已定的容量
            System.out.println("此时的size大小="+size());
            if((size()>capacity))
            {
                System.out.println("超出已定的内存容量,把链表顶端元素移除:"+eldest.getValue());
            }
            return size()>capacity;        
        }
        
        public static void main(String[] args) throws Exception{
            Scanner cin = new Scanner(System.in);
            
            System.out.println("请输入总共内存页面数: ");
            int n = cin.nextInt();
            Map<Integer,Integer> map=new LRULinkedHashMap<Integer, Integer>(n);
            
            System.out.println("请输入按顺序输入要访问内存的总共页面数: ");
            int y = cin.nextInt();
            
            System.out.println("请输入按顺序输入访问内存的页面序列: ");
            for(int i=1;i<=y;i++)
            {
                int x = cin.nextInt();
                map.put(x,  x);  
            }
            System.out.println("此时内存中包含的页面数是有:");
            //用for-each语句,遍历此时内存中的页面并输出
            for(java.util.Map.Entry<Integer, Integer> entry: map.entrySet()){
                System.out.println(entry.getValue());
            }
        }
    }

    cs