1、需要額外的虛擬儲存空間時,使用一種動態儲存裝置器分配器(dynamic memory allocator)。一個動態儲存裝置器分配器維護著一個進程的虛擬儲存空間地區,稱為堆(heap)。在大多數的unix系統中,堆是一個請求二進位0的地區;對於每個進程,核心維護著一個變數brk,它指向堆的頂部。
2、分配器將堆視為一組不同大小的塊(block)的集合來維護。每個塊就是一個連續的虛擬儲存空間組塊(chunk),要麼是已指派的,要麼是未分配的。
1)顯式分配器(explicit allocator):如通過malloc,free或C++中通過new,delete來分配和釋放一個塊。
2)隱式分配器(implicit allocator):也叫做垃圾收集器(garbage collector)。自動釋放未使用的已指派的塊的過程叫做記憶體回收(garbage collection)。
3、malloc不初始化它返回的儲存空間,calloc是一個基於malloc的封裝(wrapper)函數,它將分配的儲存空間初始化為0。想要改變一個以前已指派的塊的大小,可以使用realloc函數。
4、分配器必須對齊塊,使得它們可以儲存任何類型的資料對象。在大多數系統中,以8位元組邊界對齊。
不修改已指派的塊:分配器只能操作或者改變空閑塊。一旦被分配,就不允許修改或者移動它。
5、片段(fragmentation)
有內部片段(internal)和外部片段(external)。
外部片段:在一個已指派塊比有效載荷在時發生的。(如對齊要求,分配最小值限制等)
外部片段:當空閑儲存空間合計起來足夠滿足一個分配請求,但是沒有一個單獨的空閑塊足夠大可以來處理這個請求時發生的。
6、隱式空間鏈表
放置分配的塊的策略有:首次適配(first fit),下一次適配(next fit),和最佳適配(best fit)。
如果空閑塊已經最大程度的合并,而仍然不能產生一個足夠大的塊,來滿足要求的話,分配器就會向核心請求額外的堆儲存空間,要麼是通過調用nmap,要麼是通過調用sbrk函數;分配器都會將額外的(增加的)儲存空間轉化成一個大的空閑塊,將這個塊插入到空閑鏈表中,然後將被請求的塊放置在這個新的空閑塊中。
7、書中對分配器的設計舉了一個小例子,10.9.12節。
8、一種流行的減少分配時間的方法,稱為分離儲存(segregated storage),維護多個空閑鏈表,其中每個鏈表中的塊有大致相等的大小。
關於“簡單分離儲存”、“分離適配”、“夥伴系統”等概念,10.9.14節進行了敘述。