面试题答案
一键面试关键数据结构
- Redis对象(redisObject):这是Redis中所有数据类型的基础结构。它包含了对象的类型(如字符串、哈希、列表等)、编码方式、引用计数以及指向实际数据的指针等信息。引用计数机制用于跟踪对象被引用的次数,当引用计数变为0时,该对象就可以被回收。例如,当一个客户端对某个键值对进行DEL操作时,对应值对象的引用计数会减1 。
- 字典(dict):Redis使用字典来存储键值对。字典中的每个键值对都关联着一个redisObject。在回收内存时,需要遍历字典来查找不再被使用的键值对。例如,在执行FLUSHDB等清空数据库操作时,就是遍历整个字典,将其中所有的键值对对象的引用计数减1(如果有其他地方引用这些对象的话),进而触发内存回收。
- 链表(adlist):对于一些数据类型,如列表(list),Redis内部使用链表来实现。链表节点中包含指向前一个和后一个节点的指针以及节点值(也是redisObject)。当列表中的元素被删除时,对应的节点对象的引用计数会变化,若变为0则可回收其内存。
内存管理优化及提升回收效率的方法
- 基于引用计数的即时回收:利用redisObject的引用计数机制,当对象的引用计数变为0时,立即释放该对象占用的内存。例如,对于一个简单的字符串对象,当它不再被任何键引用时,直接释放其占用的内存空间,减少内存碎片的产生。
- 惰性删除与定期删除结合:对于字典中的键值对,采用惰性删除和定期删除策略。惰性删除是指在客户端访问某个键时,检查该键是否过期,如果过期则删除并回收内存。定期删除则是Redis在后台定期随机检查一部分键,删除过期键并回收内存。通过这两种方式结合,可以在不影响主线程性能的前提下,及时回收过期键值对占用的内存。
- 内存碎片整理:Redis提供了内存碎片整理的功能。当发现内存碎片率过高时,可以通过配置参数或者执行特定命令,让Redis对内存进行整理,将碎片化的空闲内存合并,提高内存利用率。这一过程中,需要操作上述数据结构,重新组织对象在内存中的布局,减少内存空洞。例如,对于链表结构的数据,在整理内存时可能会重新分配节点的内存地址,使它们在内存中更加紧凑。