uClibc 是嵌入式 Linux 最常用的 C 函式庫,其 malloc 實作採用簡潔的堆管理結構。本文剖析 heap、heap_free_area (FA) 結構、初始化流程、FA 操作巨集、malloc/free 核心邏輯,幫助理解用戶空間記憶體分配器運作。
struct heap {
struct heap_free_area *free_areas; // 空閒區循環鏈表頭
#ifdef HEAP_USE_LOCKING
pthread_mutex_t lock; // 多執行緒保護
#endif
};
struct heap_free_area { // 簡稱 FA
size_t size; // 空閒區大小(含 FA 本身)
struct heap_free_area *next, *prev; // 雙向循環鏈表
// 注意:FA 結構體緊接在空閒區記憶體之後
};
// 全域堆物件
struct heap __malloc_heap = HEAP_INIT_WITH_FA(initial_fa);
// 靜態初始 FA:256 bytes 空閒區 + FA 結構
HEAP_DECLARE_STATIC_FREE_AREA(initial_fa, 256);
// 展開後:
static struct {
char space[256 - sizeof(struct heap_free_area)];
struct heap_free_area _fa;
} initial_fa = { "", { 256, 0, 0 } };
sbrk/mmap 擴展。FA+1 指向空閒區末端。| 巨集 | 定義 | 用途 |
|---|---|---|
| HEAP_FREE_AREA_SIZE(fa) | (fa)->size | 取得空閒區大小 |
| HEAP_FREE_AREA_START(fa) | (void *)((char *)(fa + 1) - (fa)->size) | 空閒區起始位址 |
| HEAP_FREE_AREA_END(fa) | (void *)(fa + 1) | 空閒區結束位址(FA 位址) |
| HEAP_MIN_FREE_AREA_SIZE | HEAP_ADJUST_SIZE(sizeof(struct heap_free_area) + 32) | 最小保留空閒區(避免碎片) |
| 特性 | uClibc malloc | glibc malloc (ptmalloc) |
|---|---|---|
| 演算法 | 簡單首次適配 + 循環鏈表 | 多 arena + fastbin/smallbin/largebin + tcache |
| 多執行緒 | 單一全域鎖 | 每 arena 獨立鎖 + thread-local cache |
| 碎片處理 | 基礎合併 | 積極合併 + malloc_trim + arena 複用 |
| 程式碼量 | ~1000 行 | ~5000 行 |
| 適用場景 | 嵌入式、資源受限 | 桌面/伺服器、高併發 |
MALLOC_CHECK_=1 環境變數啟用一致性檢查。mtrace() 追蹤分配/釋放配對。__malloc_hook/__free_hook 注入記錄邏輯。理解 uClibc malloc 簡潔設計,有助於嵌入式系統記憶體洩漏排查、碎片分析與自定義分配器開發。