通用分配器(malloc/new)雖已高度優化,但特定應用(高頻小物件、固定大小區塊、多執行緒競爭)仍有提升空間。GCC、Apache、SQL Server 皆實作專屬分配器。自訂分配器可將分配週期從數百時脈降至個位數。
採用 Mixin 模式(參數化基底類別),每層僅實作 malloc/free,可組合出靈活的分配策略。
template
struct Allocator : public Super {
void* malloc(size_t sz);
void free(void* p);
enum { Alignment = sizeof(double) };
size_t getSize(const void* p); // 可選
};
struct MallocHeap {
void* malloc(size_t sz) { return std::malloc(sz); }
void free(void* p) { std::free(p); }
size_t getSize(void* p) { return _msize(p); } // MSVC 專用
};
template
struct UseSizeHeap : public Super { // 僅提供 getSize
static size_t getSize(const void* ptr) {
return ((FreeObject*)ptr - 1)->sz;
}
protected:
union FreeObject { size_t sz; double _dummy; }; // 對齊用
};
template
class SizeHeap : public UseSizeHeap { // 實作 malloc/free 並記錄大小
using FreeObject = typename UseSizeHeap::FreeObject;
public:
void* malloc(size_t sz) {
FreeObject* ptr = (FreeObject*)SuperHeap::malloc(sz + sizeof(FreeObject));
ptr->sz = sz;
return ptr + 1; // 傳回使用者資料區起始位址
}
void free(void* p) { SuperHeap::free((FreeObject*)p - 1); }
};
設計精華: 將 getSize 抽離為 UseSizeHeap,系統若已提供大小查詢(如 MSVC _msize)可直接用 MallocHeap,避免重複儲存浪費空間。
針對熱門大小區間維護單向鏈結串列,分配/釋放 O(1)、無額外記憶體開銷(指標存於釋放區塊內)。
template
struct FLHeap {
~FLHeap() { // 釋放殘留區塊
while (myFreeList) {
FreeObject* next = myFreeList->next;
Super::free(myFreeList);
myFreeList = next;
}
}
void* malloc(size_t s) {
if (s < S1 || s > S2) return Super::malloc(s);
if (!myFreeList) return Super::malloc(S2);
void* p = myFreeList;
myFreeList = myFreeList->next;
return p;
}
void free(void* p) {
size_t s = getSize(p);
if (s < S1 || s > S2) return Super::free(p);
FreeObject* obj = reinterpret_cast(p);
obj->next = myFreeList;
myFreeList = obj;
}
private:
struct FreeObject { FreeObject* next; };
FreeObject* myFreeList = nullptr;
};
typedef FLHeap, 24, 32> SmallObjectHeap;
C realloc 會 memcpy,不適用 C++ 物件(需呼叫建構/解構函式)。HeapLayers 擴充介面支援 expand:
template
struct Allocator : public T {
void* malloc(size_t sz);
void free(void* p);
size_t expand(void* p, size_t min, size_t max); // 嘗試原地擴充
};
頂層堆預設回傳 0 表示不支援。向量 push_back 可受益於原地擴充,效能提升 2 倍以上(Metrowerks 實測)。
| 分類 | 層名稱 | 功能 |
|---|---|---|
| 頂層堆 | MallocHeap | 封裝 malloc/free |
| MmapHeap | 虛擬記憶體對應 | |
| SbrkHeap | 連續堆疊擴展 | |
| 區塊管理 | ChunkHeap | 固定大小區塊管理 |
| CoalesceHeap | 區塊合併/分割 | |
| FreelistHeap | 釋放清單 | |
| HybridHeap | 小/大物件分流 | |
| SegHeap | 一般分離策略 | |
| StrictSegHeap | 嚴格分離策略 | |
| 工具層 | ANSIWrapper | ANSI malloc 相容 |
| DebugHeap | 偵測越界/重複釋放 | |
| LockedHeap | 執行緒安全鎖定 | |
| ProfileHeap | 碎片統計 | |
| ThreadHeap | 執行緒私有堆 | |
| TraceHeap | 分配追蹤日誌 | |
| 特殊用途 | ObstackHeap | 堆疊式/快速調整大小 |
| ZoneHeap | 區域分配器 | |
| XallocHeap | 優化堆疊行為 | |
| 通用堆 | KingsleyHeap | 快速但碎片多 |
| LeaHeap | 速度較慢但碎片少 |
FLHeap 析構即範例)。