Redis内存回收:LRU算法
2015-03-27 23:16
239 查看
Redis内存回收:LRU算法
http://www.cnblogs.com/WJ5888/p/4371647.htmlRedis:https://github.com/zwjlpeng/Redis_Deep_Read
Redis中采用两种算法进行内存回收,引用计数算法以及LRU算法,在操作系统内存管理一节中,我们都学习过LRU算法(最近最久未使用算法),那么什么是LRU算法呢
LRU算法作为内存管理的一种有效算法,其含义是在内存有限的情况下,当内存容量不足时,为了保证程序的运行,这时就不得不淘汰内存中的一些对象,释放这些对象占用的空间,那么选择淘汰哪些对象呢?LRU算法就提供了一种策略,告诉我们选择最近一段时间内,最久未使用的对象将其淘汰,至于为什么要选择最久未使用的,可以想想,最近一段时间内使用的东西,我们是不是可能一会又要用到呢~,而很长一段时间内都没有使用过的东西,也许永远都不会再使用~
在操作系统中LRU算法淘汰的不是内存中的对象,而是页,当内存中数据不足时,通过LRU算法,选择一页(一般是4KB)将其交换到虚拟内存区(Swap区)
LRU算法演示
这张图应该画的还行吧,用的是www.draw.io,解释如下,假设前提,只有三块内存空间可以使用,每一块内存空间只能存放一个对象,如A、B、C...
1、最开始时,内存空间是空的,因此依次进入A、B、C是没有问题的
2、当加入D时,就出现了问题,内存空间不够了,因此根据LRU算法,内存空间中A待的时间最为久远,选择A,将其淘汰
3、当再次引用B时,内存空间中的B又处于活跃状态,而C则变成了内存空间中,近段时间最久未使用的
4、当再次向内存空间加入E时,这时内存空间又不足了,选择在内存空间中待的最久的C将其淘汰出内存,这时的内存空间存放的对象就是E->B->D
LRU算法的整体思路就是这样的
算法实现应该采用怎样的数据结构
队列?那不就是FIFO算法嘛~,LRU算法最为精典的实现,就是HashMap+Double
LinkedList,时间复杂度为O(1),具体可以参考相关代码
REDIS中LRU算法的实际应用,在Redis
1.0中并未引入LRU算法,只是简单的使用引用计数法,去掉内存中不再引用的对象以及运行一个定时任务serverCron去掉内存中已经过期的对象占用的内存空间,以下是Redis
1.0中CT任务的释放内存中的部份代码
2.9.11代码中的LRU算法淘汰策略,在2.9.11版本中与LRU算法相关的代码主要位于object.c以及redis.c两个源文件中, 再分析这两个文件关于LRU源代码之前,让我们先看一下,Redis
2.9.11版本中关于LRU算法的配置,配置文件在redis.conf文件中,如下所示
1.volatile-lru:从设置了过期时间的数据集中,选择最近最久未使用的数据释放
2.allkeys-lru:从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放
3.volatile-random:从设置了过期时间的数据集中,随机选择一个数据进行释放
4.allkeys-random:从数据集中(包括了设置过期时间以及未设置过期时间)随机选择一个数据进行入释放
5.volatile-ttl:从设置了过期时间的数据集中,选择马上就要过期的数据进行释放操作
6.noeviction:不删除任意数据(但redis还会根据引用计数器进行释放呦~),这时如果内存不够时,会直接返回错误
默认的内存策略是noeviction,在Redis中LRU算法是一个近似算法,默认情况下,Redis随机挑选5个键,并且从中选取一个最近最久未使用的key进行淘汰,在配置文件中可以通过maxmemory-samples的值来设置redis需要检查key的个数,但是栓查的越多,耗费的时间也就越久,但是结构越精确(也就是Redis从内存中淘汰的对象未使用的时间也就越久~),设置多少,综合权衡吧~~~
在redis.h中声明的redisObj定义的如下:
- 1)=2^24 - 1,单位是毫秒,你可以算一下这么多毫秒,可以表示多少年~~
server.lruclock在redis.c中运行的定时器中进行更新操作,代码如下(redis.c中的定时器被配置中100ms执行一次)
lru进行赋值操作的,代码位于object.c中,如下所示
有了上述的基础,下面就是最为关键的部份了,REDIS中LRU算法,这里以volatile-lru为例(选择有过期时间的数据集进行淘汰),在Redis中命令的处理时,会调用processCommand函数,在ProcessCommand函数中,当在配置文件中配置了maxmemory时,会调用freeMemoryIfNeeded函数,释放不用的内存空间
以下是freeMemoryIfNeeded函数的关于LRU相关部份的源代码,其他代码类似
相关文章推荐
- Redis内存回收:LRU算法
- Redis内存回收:LRU算法
- Redis内存回收:LRU算法
- Redis内存回收:LRU算法
- Redis内存回收:LRU算法
- Redis深入之内存回收和对象共享
- Redis内存回收:LRU算法
- Redis的内存回收机制
- redis内存监控与回收
- Redis深入之内存回收和对象共享
- redis之一内存回收
- 通过redis-rdb-tools分析redis内存使用量
- JVM中内存回收深入分析,各种垃圾收集器
- 深入理解.NET内存回收机制 (转)
- .Net Core内存回收模式及性能测试对比分析
- 深入理解.NET内存回收机制
- Redis内存使用优化与存储
- 内存回收与hbase
- java内存垃圾回收模型
- redis内存优化————有着很多个域hash保存对象可以比建立很多个键值对更加节约内存