【學習筆記】3. 內存的 chunk 和 bins

1. 什麼是堆

前面的例子咱們已經知道棧是什麼。如今咱們來介紹下堆,以及堆的實現過程。html

在此以前,咱們先來回顧下進程的模型數組

clipboard.png

圖中的:heap 部分,就是咱們所說的堆,咱們能夠經過移動 brk 指針 來動態擴充。
或者使用 mmap 申請大的內存塊。緩存

1.1 堆在進程中的地址分佈

咱們能夠經過查看進程消息,查看進程的地址狀態學習

cd /proc/self
cat maps

clipboard.png

clipboard.png

知道了堆在進程中的位置,咱們來看下堆的保存形式。spa

1.2 堆的申請方式

堆在進程中主要存在二個地方,一個是heap ,一個是mmap mamp 主要用於存放動態連接庫。3d

申請方式:
堆能夠經過 malloc 或者 mmap 向系統內核空間申請堆空間。指針

  • 對於通常大小的堆的申請,使用malloc
  • 對於大於128K的申請,使用 mmap。
固然這些能夠經過配置項修改

1.3 堆的結構體

clipboard.png

注 :mchunk_prev_size : 上一個chunk 的大小。 便於管理,爲了後續的chunk 合併code

1.3.1 已分配出去的chunk

clipboard.png

特別注意 : 申請返回的指針,指向的 user data。
因此若是申請的是 24k,那麼堆實際的空間大小 > 24k,由於它包含了頭信息視頻

1.3.2 空閒的chunk

通常會是 free 掉的,或者截取剩下的chunkhtm

clipboard.png

咱們能夠從頭部中看出,這個chunk 是否來自主進程,以及它的分配方式。

fd bk 存放鏈表的指針,雙向指針。 一個圖形能夠很好的解釋這個狀況。

clipboard.png

2. bins

2.1 爲何使用 bins

說完了chunk ,咱們緊接着談下關聯的 bins。

用戶經過系統調用,申請使用內存。 使用完以後(好比free以後,程序結束以後),不會當即的返回給內核空間。(不斷的切換用戶態和內核態,系統消耗仍是蠻大的)

因此對於heap中申請的 內存,使用完以後,不會當即釋放,而是經過鏈表的形式保存在用戶態,便於下次的再次調用。

clipboard.png

bins 按照內存的大小,一共有128個,經過數組的形式來維護起來。

clipboard.png

2.2 bins 的分類

咱們能夠從上圖中,看出,bins 有

  1. Fast bins
  2. unsorted bins
  3. Small bins
  4. Large bins

small bins : 小於 512B 的chunk
large bins : 512B - 128K的 chunk
unsorted bins : 通常free 的chunk 大部分會存放到unsorted bins 裏面,等待下次申請時候,再分配。 另外切割剩下的部分也會被放到 unsorted bins。 因此更多的像是一個temp ,中轉站
fast bins : 至關於 bins 的緩存,採用單鏈表的形式,便於快速查詢使用。通常都是比較小的chunk,大小是0-64B。

2.3 bins 的調用順序

  1. fast bins。 針對小字節的chunk ,第一步先從 fast chunk 裏面查找。 由於是單鏈表,且是相同大小的,速度比較快。
  2. small bins : 單個鏈表下chunk大小相同,不一樣鏈表的chunk間隔是8B。
  3. unsorted bins: 先查詢 unsorted bins 有沒有合適的,若是沒有,會把 fast bins 中的bins 拿過來,用於合併和切割。 而後分配到 small bins 和 large bins。
  4. large bins,一個鏈表中大小不同,是處於一個範圍內,間隔也不相同。
  5. top chunk。 對於從large bins 查找不到的內存塊,須要從heap 旁的chunk 去申請。能夠經過移動brk 指針
  6. mmap chunk。 對於大於 128k,須要從mmap 中申請

100. 致敬

若有不詳,請參考王老師的精彩講解 堆棧管理
學習過程當中,得到了極大的知足感,把以前的一些東西串聯了起來。十分感謝 王利濤老師
在此表示感謝。
PS:本文中全部的資源和圖片均來自視頻中
另外十分推薦一本書 深刻理解計算機系統

相關文章
相關標籤/搜索