malloc的實現(xiàn):為了每次分配內(nèi)存不進行系統(tǒng)調(diào)用(系統(tǒng)調(diào)用比較耗時),運行庫會通過系統(tǒng)調(diào)用一次性分配一大塊內(nèi)存,然后零售給程序。
可以用來分配堆內(nèi)存的兩個系統(tǒng)調(diào)用:
- brk(): 將break往高地址移動(top of heap),多出來的空間為heap空間。
- mmap(): 通過mmap申請一塊匿名內(nèi)存空間。
在數(shù)據(jù)段和共享庫之間的區(qū)域都可以用來分配堆空間。linux 2.6之后共享庫的加載地址被放在了0xbf000000處,可以占用大約2.9G左右的空間,不過還是要受內(nèi)存大小+虛擬內(nèi)存空間大小的限制。
堆分配算法:
- 空閑鏈表

Paste_Image.png
空閑區(qū)域由鏈表鏈接在一起,分配時首先查找可以容納請求大小的一個空閑塊,然后將這個塊分成兩部分,一部分為程序請求的區(qū)域,一部分為剩余空間,再把剩余空間放回鏈表。如果剩余空間為0,則將其從鏈表中刪除。
分配給程序的內(nèi)存塊通常增加4個字節(jié)存儲內(nèi)存塊的大小,方便釋放。
- 位圖
將堆內(nèi)存分為相同大小的塊,用戶申請內(nèi)存時,分配整數(shù)個塊給用戶,已分配區(qū)域的一個塊為頭,其余的稱為body。一個塊的狀態(tài)為,head/body/free三種狀態(tài),可以用兩位來表示。

Paste_Image.png
對應(yīng)的位圖為:

缺點是:分配必須是塊大小的整數(shù)倍,容易產(chǎn)生浪費
堆分配算法往往是復(fù)合的,小于64字節(jié)采用對象池,大于512字節(jié)采用最佳適配算法,64到512字節(jié)采用最佳折中策略。