首页 > 数据库 >Redis内存回收与对象共享实现示例

Redis内存回收与对象共享实现示例

来源:互联网 2026-07-25 08:43:15

Redis通过引用计数管理内存,计数归零即释放对象。对象共享允许多个键共用同一值,但仅对0到9999的整数字符串对象实施共享,以平衡验证复杂度与内存节约。这种机制减少了重复存储,提升了内存利用率。

Redis中的内存回收

C语言没有自带垃圾回收机制,那Redis是怎么做到“用完就释放”的?它其实在自己的对象系统里,通过一套引用计数方案,实现了内存的自动管理——程序跟踪每个对象的引用计数,一旦计数归零,就立刻回收内存。这个计数信息记录在redisObject结构的refcount属性中:
typedef struct redisObject {
    // ...
    // 引用计数
    int refcount;
    // ...
} robj;
引用计数的变化规律很直观,就是一套“加减游戏”:
  • 创建新对象时,引用计数初始化为1;
  • 每次有新的程序用到这个对象,计数就加一;
  • 当程序不再使用它,计数就减一;
  • 一旦计数降到0,对象占用的内存就被释放。
下表列出了三个核心操作函数:
函数 作用
incrRefCount 将对象的引用计数值加一。
decrRefCount 将对象的引用计数值减一,当计数为0时释放对象。
resetRefCount 将引用计数直接设为0,但不释放对象(用于需要重新设置计数的场景)。

对象的生命周期

一个对象从生到死,通常经历三个阶段:创建、操作、释放。来看个简短的例子:
// 创建一个字符串对象 s,引用计数为 1
robj *s = createStringObject(...)
// 对象 s 执行各种操作 ...
// 将对象 s 的引用计数减一,使其变为 0,释放对象
decrRefCount(s)

对象共享

引用计数不仅用来回收内存,还有一个重要角色——对象共享。举个简单的例子:假设键A需要一个值为100的字符串对象,我们创建了一个。随后键B也需要一个同样的100,此时有两种做法:要么再新建一个字符串对象,要么让键A和键B共享同一个对象。显然,后者更省内存。

要让多个键共享同一个值对象,只需两步:

  1. 把数据库键的值指针指向已有的值对象;
  2. 将被共享对象的引用计数加一。
Redis内存回收与对象共享实现示例

共享对象对节约内存效果显著——数据库中相同值对象越多,节省得就越明显。Redis在初始化服务器时,会预先创建一万个字符串对象,对应从09999的所有整数值。当需要这些值时,直接使用共享对象,而非新建。

长期稳定更新的攒劲资源: >>>点此立即查看<<<

但这里有个关键限制:只有当共享对象和目标对象完全相同时,才能共享。验证两者是否一致,复杂度随对象复杂程度飙升:

  • 共享整数值字符串对象:验证复杂度O(1);
  • 共享字符串值的字符串对象:验证复杂度O(N);
  • 共享列表、哈希等复杂对象:验证复杂度可能达到O(N)。

因此,尽管共享更复杂的对象能节约更多内存,但受限于CPU时间开销,Redis最终只对包含整数值的字符串对象进行共享。这也是实践中一个很聪明的权衡:用少量内存预算,换取极高的验证效率。

Redis内存回收与对象共享实现示例

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备2026025700号-3 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。