引言
分享一些redis内存回收和共享的知识整理
关于对象的回收
我们都知道Redis是基于c语言开发的,c语言没有垃圾回收机制,所以Redis自己实现了一套垃圾回收机制,Redis的垃圾回收机制是通过计数来实现的。
基本逻辑是:
创建对象时计数被初始化后为1
当对象被新的逻辑使用,其计数加1
对象被逻辑用完,其计数减一
当对象的计数为0时,对象的内存被释放
在client端可以用 object refcout key 来查看其计数
对象的共享
在Redis中,对象可以实现共享。如下操作
redis:10>set a 1
“OK”
redis:10>object refcount a
“2”
redis:10>set b 1
“OK”
redis:10>object refcount b
“3”
有个问题,为什么对象刚被创建上计数就是2呢?后来经过查阅其他资料找到了答案,为了实现共享,1这个值需要服务程序来维护,故加上建a对它的引用,导致计数为2
在创建b时,因为b给的也是1,所以实现了和a的值对象共享,此时计数变为3。
后续伴随着del b ; del a 1这个值对象计数主键变成0被回收。
另外,如果值是字符串是不能共享的,如下操作:
redis:10>set aa ‘s’
“OK”
redis:10>object refcount aa
“1”
redis:10>set bb ‘s’
“OK”
redis:10>object refcount bb
“1”
自己线上redis:10>
字符串不被共享的原因是处于效率考虑,共享的前提是,两个值完全一样才能共享,那判定是否完全一样就需要对不比,比如我们比较int类型时,直接就是数值比较即可,也就是O(1)的复杂度,但是如果是字符串,我们需要逐个对比,复杂度为O(N)
共享对象的好处,显而易见,充分的节约内存,毕竟Redis是完全基于内存的,时刻要在内存节约和效率上权衡
思考
我们思考一下,如果在使用redis的时候,我们如果尽可能的使用数字去表示逻辑,是可以在一定的情况下节省Redis的内存占用的,比如说我们的逻辑控制使用数字在1-1000之间(具体共享对像的数量可以通过变量REDIS_SHARED_INTEGERS修改),而有大量的key需要使用这些数字,那是不是就可以依赖这个共享模式实现内存节约呢,共享免去了创建带来的额外开销,还能带来创建的性能提升。