1. malloc筆記
1.1 基礎概念
1.dynamic memory allocators:應用程序運行期間申請的內存(malloc)。
2.堆:dynamic memory allocator管理的進程內存區域
3.types of allocator:隱式分配器(new and garbage collection)和顯示分配器(malloc & free)
1.2 explicit allocator
1.malloc、free、realloc
2.16-byte (x86-64) alignment on 64-bit systems
3.內部碎片產生的原因:
- 維持堆所需的數據結構開銷
- 對齊的需要
- 分配器實現的策略(比如,to return a big block to satisfy a small request)
4.外部碎片:Occurs when there is enough aggregate heap memory, but no single free block is large enough。(大塊被劃分成小塊,雖然整個空閒內存能夠放下程序,但是找不到單獨的一塊去存放)
5.keep track of free blocks:顯式、隱式鏈表、Segregated free list(Different free lists for different size classes)、Blocks sorted by size(紅黑樹,長度爲key)
1.2.1 隱式空閒鏈表
1.block structures
typedef struct block
{
word_t header;//包含1bit的是否分配、剩下的表示payload大小
unsigned char payload[0];
} block_t;
2.Header access
- Getting allocated bit from header
return header & 0x1;
- Getting size from header
return header & ~0xfL;
- Initializing header
block->header = size | alloc;
3.Traversing list
static block_t *find_next(block_t *block)
{
return (block_t *) ((unsigned char *) block
+ get_size(block));
}
- Finding a Free Block
- first fit
static block_t *find_fit(size_t asize)
{
block_t *block;
for (block = heap_start; block != heap_end;
block = find_next(block)) {
{
if (!(get_alloc(block))
&& (asize <= get_size(block)))
return block;
}
return NULL; // No fit found
}
- next fit
- best fit
5.Allocating in Free Block and Splitting Free Block
6.Freeing a Block and Coalescing and Bidirectional Coalescing
1.2.2 顯式空閒鏈表
1.Unordered(插入時間複雜度O(1))
- LIFO (last-in-first-out) policy
- FIFO (first-in-first-out) policy
- Address-ordered policy(插入時間複雜度O(n))
1.2.3 Segregated List
1.按照不同的大小劃分不同的List
2.To allocate a block of size n:
- Search appropriate free list for block of size m > n (i.e., first fit)
- If an appropriate block is found:
Split block and place fragment on appropriate list
If no block is found, try next larger class - Repeat until block is found
3.If no block is found:
- Request additional heap memory from OS (using sbrk())
- Allocate block of n bytes from this new memory
- Place remainder as a single free block in appropriate size class.
1.3 隱式內存管理(垃圾收集)
1.How does the memory manager know when memory can be freed?
- In general we cannot know what is going to be used in the future since it depends on conditionals
- But we can tell that certain blocks cannot be used if there are no pointers to them
2.Must make certain assumptions about pointers
- Memory manager can distinguish pointers from non-pointers
- All pointers point to the start of a block
- Cannot hide pointers (e.g., by coercing them to an int, and then back again):比如c語言,可以任意的使用指針,所以c語言不能夠自動清理垃圾
3.採用有向圖標記:堆中分配的block看成節點,邊看成指針。利用dfs算法,可以標記現在或者未來依然會使用的堆中的block。
malloc實驗
看了幾個博客,用隱式鏈表的話能得個50分左右,採用顯式空閒鏈表+LIFO或者顯式空閒鏈表+地址排序能得個80分左右,採用Segregated List得分較高,有100分左右。