1.内存回收
因为C语言并不具备自动内存回收功能,所以Redis在自己的对象系 统中构建了一个引用计数(reference counting)技术实现的内存回收机 制,通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的 时候自动释放对象并进行内存回收
每个对象的引用计数信息由redisObject结构的refcount属性记录
基本结构:
typedef struct redisObject {
// ...
//
引用计数
int refcount;
// ...
} robj;
·在创建一个新对象时,引用计数的值会被初始化为1;
·当对象被一个新程序使用时,它的引用计数值会被增一;
·当对象不再被一个程序使用时,它的引用计数值会被减一;
·当对象的引用计数值变为0时,对象所占用的内存会被释放
2.对象共享
除了用于实现引用计数内存回收机制之外,对象的引用计数属性还 带有对象共享的作用
假设键A创建了一个包含整数值100 的字符串对象作为值对象
如果这时键B也要创建一个同样保存了整数值100的字符串对象作为值对象
1)为键B新创建一个包含整数值100的字符串对象;
2)让键A和键B共享同一个字符串对象;
以上两种方法很明显是第二种方法更节约内存。 在Redis中,让多个键共享同一个值对象需要执行以下两个步骤:
1)将数据库键的值指针指向一个现有的值对象;
2)将被共享的值对象的引用计数增一
note
目前来说,Redis会在初始化服务器时,创建一万个字符串对象, 这些对象包含了从0到9999的所有整数值,当服务器需要用到值为0到 9999的字符串对象时,服务器就会使用这些共享对象,而不是新创建对象。
举例说明:
如果我们创建一个值为100的键A,并使用OBJECT REFCOUNT命令查看键A的值对象的引用计数,我们会发现值对象的引用计数为2
redis> SET A 100
OK
redis> OBJECT REFCOUNT A
(integer) 2
引用这个值对象的两个程序分别是持有这个值对象的服务器程序, 以及共享这个值对象的键A
如果这时我们再创建一个值为100的键B,那么键B也会指向包含整 数值100的共享对象,使得共享对象的引用计数值变为3
note2
这些共享对象不单单只有字符串键可以使用,那些在数据结 构中嵌套了字符串对象的对象(linkedlist编码的列表对象、hashtable编 码的哈希对象、hashtable编码的集合对象,以及zset编码的有序集合对 象)都可以使用这些共享对象
3.对象的空转时长
redisObject结构包含的最后一个属性为lru属性,该属性记录了对象最后 一次被命令程序访问的时间
typedef struct redisObject {
// ...
unsigned lru:22;
// ...
} robj;
OBJECT IDLETIME命令可以打印出给定键的空转时长,这一空转时长就是通过将当前时间减去键的值对象的lru时间计算得出的
这个命令在访问键的值 对象时,不会修改值对象的lru属性
redis> SET msg "hello world"
OK
#
等待一小段时间
redis> OBJECT IDLETIME msg
(integer) 20
#
等待一阵子
redis> OBJECT IDLETIME msg
(integer) 180
#
访问msg
键的值
redis> GET msg
"hello world"
#
键处于活跃状态,空转时长为0
redis> OBJECT IDLETIME msg
(integer) 0
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/129591.html