Redis通过引用计数管理内存,计数归零即释放对象。对象共享允许多个键共用同一值,但仅对0到9999的整数字符串对象实施共享,以平衡验证复杂度与内存节约。这种机制减少了重复存储,提升了内存利用率。
redisObject结构的refcount属性中:
typedef struct redisObject {
// ...
// 引用计数
int refcount;
// ...
} robj;
引用计数的变化规律很直观,就是一套“加减游戏”:
| 函数 | 作用 |
|---|---|
incrRefCount |
将对象的引用计数值加一。 |
decrRefCount |
将对象的引用计数值减一,当计数为0时释放对象。 |
resetRefCount |
将引用计数直接设为0,但不释放对象(用于需要重新设置计数的场景)。 |
// 创建一个字符串对象 s,引用计数为 1
robj *s = createStringObject(...)
// 对象 s 执行各种操作 ...
// 将对象 s 的引用计数减一,使其变为 0,释放对象
decrRefCount(s)
100的字符串对象,我们创建了一个。随后键B也需要一个同样的100,此时有两种做法:要么再新建一个字符串对象,要么让键A和键B共享同一个对象。显然,后者更省内存。
要让多个键共享同一个值对象,只需两步:
共享对象对节约内存效果显著——数据库中相同值对象越多,节省得就越明显。Redis在初始化服务器时,会预先创建一万个字符串对象,对应从0到9999的所有整数值。当需要这些值时,直接使用共享对象,而非新建。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
但这里有个关键限制:只有当共享对象和目标对象完全相同时,才能共享。验证两者是否一致,复杂度随对象复杂程度飙升:
因此,尽管共享更复杂的对象能节约更多内存,但受限于CPU时间开销,Redis最终只对包含整数值的字符串对象进行共享。这也是实践中一个很聪明的权衡:用少量内存预算,换取极高的验证效率。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述