Redis笔记之对象的回收与共享

对象回收

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

你可能感兴趣的:(Redis笔记之对象的回收与共享)