Redis使用SDS(simple dynamic string)用作字符串默認實現。
struct sdshdr{
//已使用buf數組的字節數量,也就是字符串長度
int len;
//未使用的長度
int free;
//保存字符串
char buf[];
}
SDS遵循C語言字符串以空字符串結尾,保留1個字節的空字符串'\0',該空串不記入len中。
C語言中,獲取字符串長度需要遍歷整個字符串,時間複雜度爲O(n),SDS中有len屬性維護長度,時間複雜度爲O(1),Java裏面String不可變,初始化的時候就記錄了長度,時間複雜度啊也是O(n)。
SDS空間分配策略杜絕緩衝區溢出的可能。當需要對SDS進行修改時,API會先檢查SDS剩餘空間是否滿足需求,如不滿足會自動擴容。
SDS內存分配策略:
1.空間預分配
當SDS長度(len)小於1MB,程序會分配和len同樣大小的未使用空間,這是len===free。例如修改後字符串長度爲13字節,就會分配13字節的未使用空間,此時buf=len+free+1=13+13+1=27字節,其中1是'\0'。
當SDS被修改後長度大於1MB,程序會分配1MB的未使用空間。即使len=50MB,也還是分配1MB的未使用空間。
通過空間預分配策略,Redis可以有效減少連續修改字符串操作引起的內存分配次數。
2.惰性空間釋放:
當SDS字符串進行縮短操作時,程序不會立即重新分配內存來回收多的字節,而是用free記錄,等待將來使用。
例如SDS:abcxyz,修改成abc,SDS並不會釋放多餘出來的3個字節,而是將free=free+3,以備將來字符串增長操作時使用。
SDS是二進制安全的