对象回收
Redis在自己的对象系统中设置了一个引用计数refcount用于进行内存自动回收。
对象共享
Redis中可以通过引用计数来共享对象。
目前来说,Redis会在初始化服务器时,创建一批共享字符串对象进行共享,其中包含值为0-9999共一万个字符串对象。
//server.h
void createSharedObjects(void) {
int j;
/* Shared command responses */
shared.crlf = createObject(OBJ_STRING,sdsnew("\r\n"));
shared.ok = createObject(OBJ_STRING,sdsnew("+OK\r\n"));
...
for (j = 0; j < OBJ_SHARED_INTEGERS; j++) {
shared.integers[j] =
makeObjectShared(createObject(OBJ_STRING,(void*)(long)j));
shared.integers[j]->encoding = OBJ_ENCODING_INT;
}
...
shared.minstring = sdsnew("minstring");
shared.maxstring = sdsnew("maxstring");
}
共享字符串的引用计数被设置为INT_MAX,表示这个对象是全局对象,不会被销毁。
// server.h
#define OBJ_SHARED_REFCOUNT INT_MAX /* Global object never destroyed. */
// object.c
/* Set a special refcount in the object to make it "shared":
* incrRefCount and decrRefCount() will test for this special refcount
* and will not touch the object. This way it is free to access shared
* objects such as small integers from different threads without any
* mutex.
*
* A common patter to create shared objects:
*
* robj *myobject = makeObjectShared(createObject(...));
*
*/
robj *makeObjectShared(robj *o) {
serverAssert(o->refcount == 1);
o->refcount = OBJ_SHARED_REFCOUNT;
return o;
}
注意:尽管共享对象可以节省内存,但是对于复杂对象去比较两个对象是否相等需要消耗太多的CPU,故目前只对初始化创建的这些对象进行共享。
可以通过以下命令进行验证:
127.0.0.1:6379> set A 100
OK
127.0.0.1:6379> object refcount A
(integer) 2147483647
127.0.0.1:6379> set B 100
OK
127.0.0.1:6379> object refcount A
(integer) 2147483647
网友评论