Redis中所有字符串都是用SDS(简单动态字符串)实现的,该结构体内部定义如下:
struct sdshdr{
int len; //buf已用字节数
int free; //buf未用字节数
char buf[];
};
关于SDS的特点,可以总结为以下几点:
1. SDS遵循C字符串以空字符结尾的风格,兼容部分C字符串函数,buf在末尾默认会带上一个‘\0’字符,但是不会计算到len字段里面,因此buf的实际大小为len+free+1(1表示'\0'字符)。
2. 因为有len字段的存在,所以计算字符串长度的复杂度为O(1),这点跟C++的String类相似。
3. SDS对内存的管理采用了2种策略:
(1)空间预分配:
如果在对SDS进行修改时发现修改后的字符串长度(这里假设为new_len)不会超过修改前len与free的总和,就直接在原空间上进行操作,不需要堆内存进行重分配。反之,Redis就会对空间进行扩展,在将len修改为new_len的同时,分配min(1MB, new_len)的空间给free字段(buf未用字节数),即新的buf实际可容纳最大字节数为new_len+min(1MB, new_len)+1。
(2)惰性释放:
如果对SDS进行字符串缩短操作,不立即使用内存重分配来回收缩短之后多出来的字节,而是记录在free字段,留给以后扩展的时候用。当然,Redis也提供了适当的API让我们可以在必要的时候进行内存释放。
4. SDS的API是二进制安全的,因为SDS使用len字段来判断字符串是否结束而不是'\0'。
本文深入解析了Redis中的简单动态字符串(SDS)实现原理,包括其结构、特点及内存管理策略,如空间预分配与惰性释放机制,展示了SDS如何优化字符串操作效率。
1202

被折叠的 条评论
为什么被折叠?



