Redis数据结构——对象多态及回收

Posted codingjav

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis数据结构——对象多态及回收相关的知识,希望对你有一定的参考价值。

目录

前言

1、类型检查与命令多态

延伸阅读:为什么redis不共享包含字符串的对象?

重点回顾


前言

本篇会是Redis基础数据结构最后一篇,整个Redis基础系列将要告一段落。后面会依据

《redis设计与实现》继续分享Redis持久化、高可用、实战相关,敬请期待!!!

Redis数据结构——整数集合-intset

Redis数据结构——字典-hashtable

Redis数据结构——跳跃表-skiplist

Redis数据结构——链表-linkedlist

Redis数据结构——简单动态字符串-SDS

Redis数据结构-对象

1、类型检查与命令多态

redis中用于操作键的命令基本上可以分为两种类型。

       其中一种命令可以对任何类型的键执行,比如说del命令、expire命令、rename命令、type命令、object命令等。

       而另一种命令只能对特定类型的键执行,比如set、get、append、strlen等命令只能对字符串键键执行;hdel、hset、hget、hlen等命令只能对哈希键执行。

类型检查的实现

       类型特定命令锁进行的类型检查是通过redisObject结构的type属性来实现的:

在执行一个类型特定命令之前,服务器会先检查输入数据库键的值对象是否为执行命令所需的类型,如果是的话,服务器就对键执行指定的命令;否则,服务器将拒绝执行命令,并向客户端返回一个类型错误。

多态命令的实现

       redis除了会根据值对象的类型来判断键是否能够执行指定命令之外,还会根据值对象的编码方式,选择正确的命令实现代码来执行命令。

       举个例子,在前面介绍列表对象的编码时我们说过,列表对象有ziplist和linkedlist两种编码可用,其中前者使用压缩列表api来实现列表命令,而后者使用双端链表api来实现列表命令。

内存回收

 因为C语言并不具备自动内存回收功能,所以redis在自己的对象系统中构建了一个引用计数技术实现的内存回收机制,通过这一机制,程序可以通过跟中对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。每个对象的引用计数信息由redisObject结构的refcount属性记录:

typedef struct redisObject{       
// 
…        
//引用计数       
int refcount;        
……. 
}

对象共享

除了用于实现引用计数内存回收机制之外,对象的引用计数属性还带有对象共享的作用。目前来说,redis会在初始化服务器时,创建一万个字符串对象,这些对象包含了从0到9999的所有整数值,当服务器需要用到值为0到9999的字符串对象时,服务器就会使用这些共享对象,而不是新创建对象。(可以通过配置修改常量值)另外,这些共享对象不单单只有字符串字符串键可以使用,那些在数据结构中嵌套了字符串对象的对象(linkedlist编码的列表对象、hashtable编码的哈希对象等)都可以使用这些共享对象。

对象的空转时长

除了前面介绍介绍过的type、encoding、ptr和refcount四个属性值之外,redisObject结构包含的最后一个属性为lru属性,该属性记录了对象最后一次被命令程序访问的时间,这个时间被利用在对象回收算法中。

延伸阅读:为什么redis不共享包含字符串的对象?

       当服务器考虑将一个共享对象设置为键的值对象时,程序需要先检查给定的共享对象和键想创建的目标是否完全相同,只有在共享对象和目标对象完全相同的情况下,程序才会将共享对象用作键的值对象,而一个共享对象保存的值越复杂,验证共享对象和目标对象是否相同所需要的复杂度就会越高,消耗的cpu时间也会越多。

  • 如果共享对象是保存整数值的字符串对象,那么验证操作的复杂度为o(1)
  • 如果共享对象是保存字符串值的字符串对象,那么验证操作的复杂度为O(N)
  • 如果共享对象对象是包含了多个值(或者对象的)对象,比如列表对象或者哈希对象,那么验证操作的复杂度将会是O(N^2)

因此,尽管共享更复杂的对象可以节约更多的内存,但受到cpu时间的限制,redis只对包含整数值的字符串对象进行共享。

重点回顾

1 、redis数据库中的每个键值对的键和值都是一个对象

2、 redis公有字符串、列表、哈希、集合、有序集合五种类型的对象,每种类型的对象至少都有两种或以上的编码方式,不同的编码可以在不同的使用场景上优化对象的使用效率。

3 、服务器在执行某些命令之前,会先检查给定键的类型能否执行指定的命令,而检查一个键的类型就是检查键的值对象的类型。

4 、redis的对象系统带有引用计数实现的内存回收机制,当一个对象不再被使用时,该对象所占用的内存就会被自动释放。

5、 redis 会共享值为0到9999的字符串对象。

6、 对象会记录自己的最后一次被访问的时间,这个时间可以用于计算对象的空转时间。

 

 

 

以上是关于Redis数据结构——对象多态及回收的主要内容,如果未能解决你的问题,请参考以下文章

Redis 补充知识

java最新面试题及答案2020(二十四)

内存回收策略

redis内存回收机制及rdb和aof存储机制aof重写原理

Redis对象类型

Java代码执行顺序及多态体现