String的數據結構是一個字節數組,但簡單的獲取數組長度的時間複雜度就是O(n),這對於單線程的redis來說是不能接受的,所以string在redis中的實現是SDS類,SDS類的結構整體以下(C已忘,只能用java大體表達下):java
public class SDS { // string內容的真實長度,爲了節約內存,這裏是個泛型 // 當內容較少時,使用byte或short private T length; // 爲string分配的內存空間大小,一樣爲了節約內存,用了泛型 private T capacity; // string的真實內容,使用字節數組存儲 private byte[] content; // 特殊標記,不知道幹嗎的 private byte flags; }
如上,長度直接保存下來了--雖然二者沒什麼關聯,但我想到了mysql的Myisam引擎,也是直接將表的數據條數直接保存下來--這樣要獲取長度直接取值便可;mysql
使用debug object命令會發現,不一樣長度的string的encoding有embed和raw兩種類型,也是爲了節省空間,64字節及如下的string會使用embed存儲,以上使用RAW存儲(不一樣redis版本下可能會有不一樣的界限),之因此使用64爲界是由於內存分配函數malloc等都是一次分配2的若干次冪大小的內存,另外即便分配64字節給string使用,content也只有44字節的內存能夠存儲,緣由正是由於下面的redis頭對象也佔了坑redis
public class RedisObject { // 數據類型,只使用4bit private int4 type; // 數據的encoding類型,只使用4bit private int4 encoding; // 數據的lru信息,只使用24bit private int24 lru; // 該數據的引用計數,使用32bit private int32 refcount; // 這是個指針,指向數據對象,在64位操做系統下,使用8個字節 private Poniter *p; }
能夠發現,對象頭至少使用16個字節,而假使SDS的三個輔助屬性都只使用1字節的話,content也就只剩下64-19=45字節的空間可使用了,還有一個字節用來保存字符串的結尾字符,這個字符一般使用的是null,而在redis中使用的是\0,\0使用了1個字節,content的可用有效字符就僅剩44字節了sql