首页 > 代码库 > Redis深入之内存回收和对象共享

Redis深入之内存回收和对象共享

内存回收

C语言并不具备自动内存回收功能,Redis在自己的对象系统中构建了一个引用计数技术实现的内存回收机制,通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。每个对象的引用计数信息由redis对象结构的refcount属性记录,创建一个新对象时,引用计数值会初始化为1;对象被一个新程序使用时,它的引用计数值会被增1;不再被一个程序使用时,减1;引用计数值变为0,对象所占用的内存会被释放。

对象共享

对象的引用计数属性还带有对象共享的作用。Redis会共享值为0到9999的字符串对象。如果键A创建了一个包含整数值100的字符串对象作为值对象,键B也要创建一个同样保存了整数值100的字符串对象作为值对象,服务器可以让键A和键B共享同一个字符串对象,Redis中需要两步,1)将数据库键的值指针指向一个现有的值对象;2)将被共享的值对象的引用计数增一。共享对象机制对于节约内存非常有帮助,数据库中保存的相同值对象越多,对象共享机制就能节约越多的内存。

问:Redis为什么只对包含整数值得字符串对象进行共享?

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

如果共享对象是保存整数值的字符串对象,验证操作的复杂度O(1)

如果共享对象是保存字符串值的字符串对象,验证操作的复杂度O(N)

如果共享对象是包含多个值(比如列表对象或者哈希对象)对象,验证操作的复杂度O(N2

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

Redis深入之内存回收和对象共享