【C++內存管理】9_std::alloc 運行模式詳解

從如下連續步驟中,咱們能夠了解到 alloc 工做時的基本流程。其中包含戰備池、自由鏈表每次最多新增20個區塊、追加量、碎片處理、內存不足時的處理等概念

起始

image.png

  • free_list 數組包含16個元素,子元素分別管理不一樣內存大小的自由鏈表(單鏈表)

第一次內存申請

  • 分配器的客戶是容器,即分配器服務於容器
  • 使用 malloc 申請的內存大小可能不一樣,所以須要藉助 cookie 記錄大小信息以進行後續的內存釋放動做
  • 容器的全部元素大小已知且一致,所以能夠不使用 malloc(不使用 cookie )
  • 在 alloc 工做時,老是先把可用內存放到戰備池,再從戰備池切割適當的內存到 free_list 管理的鏈表

image.png

補充描述
  • 容器申請 32 bytes, 因爲 pool(戰備池)爲空,故使用 malloc(包含 cookie) 索取內存併成功向 pool 加註 32 x 20 x 2 + RoundUp(0>>4) = 1280 bytes, 從中切出 1 個區塊返回給容器, 19 個區塊給 list#3, 剩餘 640 bytes 備用(戰備池)
  • 戰備池:由 start_free、 end_free 指針描述
RoundUp (0>>4) : 追加量,會愈來愈大
RoundUp : 是一個函數,將一個數值(累計申請總量)調整到 16 的邊界
0 >> 4 : 0(目前的申請總量,初次值 0) / 16

無文檔可說明爲何須要使用追加量,且每次追加量值是累計申請量除以16,或許爲經驗值

第二次內存申請

image.png

補充描述
  • 圓滑鏈接線表示圖中內存塊在地址上連續
  • 直角鏈接線表示圖中內存塊在自由鏈表中連續

第三次內存申請

image.png

第四次內存申請

image.png

補充描述
  • 通過以上操做,代碼中已經建立了 4 種容器,每一個容器大小各不相同,由圖中的 4 條鏈表進行分別管理
  • 總計使用兩次 malloc

第五次內存申請

image.png

第六次內存申請

image.png

第六次內存申請

image.png

補充描述
  • 通過以上操做,代碼中已經建立了 7 中容器,每一個容器元素大小各不相同,由圖中的 7 條鏈表進行分別管理
  • 總計使用三次 malloc
  • 特別說明,若是多種容器(vector、list、queue、deque)它們所管理的對象大小相同,此時會共用同一條子自由鏈表

第七次內存申請

image.png

第八次內存申請

image.png

第九次內存申請

image.png

第十次內存申請

image.png

補充描述
  • 圖中 free_list[8] 和 free_list[9] 爲虛線,表示空鏈表(指向 null),無可用內存塊數組

    • free_list[9] 由於內存塊被回填戰備池以供給 alloc 使用
    • free_list[8] 由於惟一內存塊被使用返給客戶

第十一次內存申請

image.png

第十二次內存申請

image.png

產生的疑惑

image.png

補充描述
  • 反省 1 技術難點:cookie

    • 如何找到自由鏈表中合適大小且內存相鄰的兩個或多個節點進行合併
    • 不知道鏈表的長度,尤爲內存塊不斷動態被申請又被回收
  • 反省 2 後續講解
相關文章
相關標籤/搜索