Redis--SDS空間分配策略(len、free、buff[])


SDS結構(簡單動態字符串)

結構如下

struct stdhdr { int len //記錄buff數組中已使用字節的數量 int free //記錄buff數組中未使用字節的數量 char buff[] //字節數組,用於保存字符串 }

(1)free 屬性為0,表示這個SDS沒有分配任何未使用空間。

(2)len 屬性為5,表示這個SDS保存着一個5字節長的字符串

(3)buf 屬性是一個char類型的數組,數組的前五個字節分別保存了,'R' 'e' 'd' 'i' 's' ,而最后一個字節保存了空字符 '\0' (以空字符結尾),最后一個空字節不計算在len屬性里面。

SDS字符串和C字符串的區別

1.通過使用SDS字符串(len記錄字符串長度),使得獲取字符串長度的復雜度從O(N)變為O(1)

2.杜絕緩存區溢出,C字符串不記錄自身長度,在拼接字符串時可能造成緩存區溢出

3.通過未使用空間free,減少修改字符串帶來的內存重分配次數

 

空間預分配

空間預分配用於優化 SDS 的字符串增長操作: 當 SDS 的 API 對一個 SDS 進行修改, 並且需要對 SDS 進行空間擴展的時候, 程序不僅會為 SDS 分配修改所必須要的空間, 還會為 SDS 分配額外的未使用空間。

其中, 額外分配的未使用空間數量由以下公式決定:

  • 如果對 SDS 進行修改之后, SDS 的長度(也即是 len 屬性的值)將小於 1 MB , 那么程序分配和 len 屬性同樣大小的未使用空間, 這時 SDS len 屬性的值將和 free 屬性的值相同。 舉個例子, 如果進行修改之后, SDS 的 len 將變成 13 字節, 那么程序也會分配13 字節的未使用空間, SDS 的 buf 數組的實際長度將變成 13 + 13 + 1 = 27 字節(額外的一字節用於保存空字符)。
  • 如果對 SDS 進行修改之后, SDS 的長度將大於等於 1 MB , 那么程序會分配 1 MB 的未使用空間。 舉個例子, 如果進行修改之后, SDS 的 len 將變成 30 MB , 那么程序會分配 1 MB 的未使用空間, SDS 的 buf 數組的實際長度將為 30 MB + 1 MB + 1 byte 。

通過空間預分配策略, Redis可以減少連續執行字符串增長操作所需的內存重分配次數。

 

惰性空間

釋放惰性空間釋放用於優化SDS的字符串縮短操作:當 SDS的API需要縮短 SDS保存的字符串時, 程序並不立即使用內存重分配來回收縮短后多出來的字節, 而是使用 free 屬性將這些字節的數量記錄起來, 並等待將來使用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM