任何人都可以解釋malloc()
內部工作嗎?malloc()如何在內部實現?
我有時做strace program
,我看到了很多的sbrk
系統調用,做這件事man sbrk
會談malloc()
正在使用但沒有更多。
任何人都可以解釋malloc()
內部工作嗎?malloc()如何在內部實現?
我有時做strace program
,我看到了很多的sbrk
系統調用,做這件事man sbrk
會談malloc()
正在使用但沒有更多。
系統調用sbrk
移動數據段的「邊界」。這意味着它移動了一個程序可以讀/寫數據的區域的邊界(讓它增長或縮小,儘管AFAIK沒有malloc
確實使用該方法將內存段返回給內核)。除此之外,還有mmap
用於將文件映射到內存中,但也用於分配內存(如果您需要分配共享內存,mmap
是您的操作方式)。
所以你有兩種從內核獲取更多內存的方法:sbrk
和mmap
。關於如何組織你從內核獲得的內存有各種策略。
一種天真的方式是將其分區爲通常稱爲「桶」的區域,這些區域專用於特定的結構尺寸。例如,malloc
實現可以爲16,64,256和1024字節結構創建存儲桶。如果您要求malloc
爲您提供給定大小的記憶,則會將該數字四捨五入到下一個存儲桶大小,然後爲您提供該存儲桶中的一個元素。如果你需要更大的區域malloc
可以使用mmap
直接與內核分配。如果某個尺寸的存儲桶爲空,malloc
可以使用sbrk
爲新存儲桶獲取更多空間。
有各種各樣的malloc
設計,因爲您需要在速度,開銷和避免碎片/空間有效性之間做出妥協,所以沒有人會真正實施malloc
。例如,如果一個存儲桶中的元素耗盡,實現可能會從一個更大的存儲桶中獲取一個元素,將其分解並將其添加到耗盡元素的存儲桶中。這將是相當節省空間,但不可能與每個設計。如果你通過sbrk
/mmap
獲得另一個桶,這可能會更快,更容易,但不是空間效率高。此外,設計當然必須考慮到「免費」需要以某種方式再次向malloc
提供空間。你不只是分配內存而不重用它。
如果你有興趣,在OpenSER的/ Kamailio SIP代理有兩個malloc
實現(他們需要自己的,因爲他們大量使用共享內存和malloc
不支持共享內存系統)。見:https://github.com/OpenSIPS/opensips/tree/master/mem
然後,你也可以看看GNU libc malloc
implementation,但這是一個非常複雜,IIRC。
IIRC =如果我正確回憶 – 2017-04-29 20:16:06
簡單地malloc和free的工作是這樣的:
的malloc提供訪問進程的堆。堆是C核心庫(通常爲libc)中的一個構造,它允許對象獲得進程堆上某些空間的獨佔訪問權。
堆上的每個分配稱爲堆單元。這通常由一個頭部組成,該頭部保存關於單元大小的信息以及指向下一個堆單元的指針。這使得一個堆有效地成爲一個鏈表。
當啓動一個進程時,堆包含一個單元,其中包含啓動時分配的所有堆空間。這個單元格存在於堆的空閒列表中。
當一個調用malloc,存儲器從大堆單元,其通過malloc返回截取。其餘部分形成一個由所有其餘內存組成的新堆單元。
當一個釋放內存,堆小區被添加到堆的空閒列表的末尾。隨後的malloc在空閒列表中尋找合適大小的單元格。
可以預料,堆可能會碎片化,堆管理器可能會不時嘗試合併相鄰的堆單元。
當沒有留下所需的分配空閒列表上的內存,malloc的調用BRK或SBRK這是系統調用請求從操作系統中多個存儲頁。
現在有一些修改,以優化堆操作。
同樣重要的是要認識到,簡單地brk
和sbrk
走動的程序中斷指針實際上並不分配內存,它只是設置了地址空間。在Linux上,例如,該內存將被「支持」通過時地址範圍訪問實際的物理頁面,這將導致頁面錯誤,並最終導致內核調用到頁面分配器獲得的支持頁面。
使用源,博大Cydo。 http://ftp.gnu.org/gnu/glibc/ – msw 2010-08-13 17:46:16
我認爲這個鏈接在一定程度上回答你的問題 http://stackoverflow.com/questions/1119134/how-malloc-and-free-work – Rishabh 2010-08-13 17:40:28