ptmalloc2


本文參考華庭(庄明強)的ptmalloc2 源碼剖析

  • 簡介:

ptmalloc實現了malloc(),free()以及一組其他函數,以提供動態內存管理,同時支持多線程。分配器處於用戶空間和內核空間之間,響應用戶的分配請求,向操作系統申請內存。總體思想是先“批發”一塊大內存,而后“零售”給用戶,同時也實現了高效的回收機制。

 

  • Main_area / non_main_area(主分配區和非主分配區):

在linux之前版本使用的內存分配機制只有一個主分配區,然而多線程下訪問要加鎖,所以在ptmalloc中區分出了主分區和非主分區。主分區只有一個,而非主分區可以有多個,分區一旦增加就不會減少。

主分區可以訪問heap和memory mapping segment(可調用brk()/sbrk()/mmap()),而非主分區只能訪問memory mapping segment(只可以調用mmap())。

 

  • chunk組織

ptmalloc通過chunk來管理內存,給User data前存儲了一些信息,使用邊界標記區分各個chunk。

這個是一個使用中的chunk,返回給用戶的指針是上圖的mem,在mem上方分別存放了前一個chunk的大小和本chunk的大小,chunk對齊(alignment = 2 ^n; n>=3),對於默認8字節對齊后10個bit為一定為0,則可以用后3個bit存儲其他信息。

A:1表示主分配區 0表示非主分配區

M:表示是否使用mmap()直接從進程mmap映射區域分配, 1表示是, 0表示不是。(ptmalloc認為長生命周期的大內存使用mmap,回收一個由mmap直接映射的內存時會更改mmap分配和收縮閾值,因為如果頻繁使用mmap()分配內存,每次mmap映射物理頁需要將物理頁清零,浪費系統資源)。

p:1表示前一個chunk正在使用,0表示前一個chunk為空閑。

 

  • chunk的空間復用和邊界標記法

對於空閑的chunk增加了額外的指針

 

紅色框住的只有在較大的chunk中才存在。

為了使chunk所占空間最小,使用了空間復用

由於對於ptmalloc來說每次都是向操作系統申請一大塊內存,然后分割成不同的chunk,所以對於查找上一個chunk直接可以用chunk指針減去前一個的大小,查找下一個也是同樣的道理,只用計算指針就方便的多。同時在后面的合並中也只用改結構體中相應的值即可。

p位標識了前一個chunk是否空閑,如果p為1時(前一塊正在使用),Sizeof previous chunk就沒有意義,而這塊空間就可以被上一塊有數據的chunk使用。下圖簡單地表示了chunk的空間復用

 

 

所以對於此處的next chunk中的prev域雖然是屬於他的,但里面內容卻存放的是上一個chunk的User data,而上一個chunk的size 應該為    (data + 8 - 4)align to 8B,這個就是實際分配的內存大小。

邊界標記法:簡單來說類似於循環首次適應算法,因為空閑的chunk組成了一個雙向循環鏈表,確保了內存分配不會因為首次適應積攢在頭部。

 

  • 內存分配過程:(分配回收過程文檔中有詳細說明)

 

  • 內存回收過程

 

 

  • 配置選項
  1. M_MXFAST:設置fast bin中最大大小。多使用fast bin效率很高但設置的過大會導致內存隨便過多,頻繁清理合並fast bin會因加鎖而影響效率。
  2. M_TRIM_THRESHOLD:設置mmap收縮閾值,-1關閉收縮
  3. M_MMAP_THRESHOLD:設置mmap分配閾值,默認128k
  4. M_MMAP_MAX:設置使用mmap分配內存的最大塊數,默認64k

 

  • 避免Glibc內存暴增
  1. 后分配的先釋放,因為ptmalloc收縮內存只能夠從top chunk開始,所以當離top chunk最近的那一塊內存沒有釋放時,ptmalloc是不會釋放收縮的。
  2. 防止內存泄漏,如果泄露的剛好是top chunk最近的內存,則無法收縮
  3. 不合適管理長生命周期的內存
  4. 可以通過優化配置按照實際情況優化
  5. 多線程不適合 對於非主分區一旦增加不會減少,所以在對鎖競爭激烈時,會快速的增加非主分配去,當到達最大值時,無法增加非主分配區從而降低了效率。
  6. 對於小塊的內存需要精確匹配,而對於large bin中則需要切割,多線程下由於不斷的分割會產生很多內存碎片,對內存碎片的清理要加鎖,會降低效率。

 


免責聲明!

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



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