傳統 allocator 要求精確配對 new/delete,boost::object_pool 打破此教條:允許忘記釋放。既支援手動 destroy(),又在池析構時自動回收殘留物件並呼叫解構函數。這正是「GC Allocator」核心規格 —— 具備垃圾回收能力的配置器。
void func() {
boost::object_pool<X> alloc;
X* obj1 = alloc.construct(); // 未手動釋放
X* obj2 = alloc.construct();
alloc.destroy(obj2); // 僅釋放 obj2
} // alloc 析構時自動銷毀 obj1 並釋放記憶體
| 特性 | AutoFreeAlloc | boost::object_pool |
|---|---|---|
| 手動釋放 | 不支援 | 支援 (destroy) |
| 回收時機 | 僅池析構時一次性全釋放 | 池析構時逐個檢查並銷毀未釋放者 |
| 型別 | 通用 (任意型別) | 單一型別 (T) |
| 定位 | 通用型 GC Allocator | 非通用型、特定型別 GC Allocator |
結論:object_pool 功能更完備,但侷限於單一型別;AutoFreeAlloc 通用但僅適合「階段性批量配置、統一釋放」場景。
核心挑戰:析構時需區分「已手動釋放」與「未釋放」節點,僅對後者呼叫解構函數。解法:
pool::ordered_malloc / ordered_free 維護有序的記憶體塊列表 (MemBlockList) 與自由節點列表 (FreeNodeList)。MemBlock,對每個塊內節點以「雙指標合併」 (類似 std::set_intersection) 快速判斷是否在 FreeNodeList 中。~T();最後釋放整個 MemBlock。// 關鍵邏輯片段
for (char* i = block_begin; i != block_end; i += partition_size) {
if (i == freed_iter) { freed_iter = next_free; continue; } // 已手動釋放
static_cast<T*>(i)->~T(); // 未釋放,呼叫解構函數
}
UserAllocator::free(block_begin);
有序列表使「集合求交」達到 O(N) 而非 O(N²),關鍵效能優化。
boost::object_pool 證明了:在庫層面引入 GC 語義不需語言擴展,即可大幅降低記憶體洩漏風險。它是「半自動 GC」在 C++ 中落地的重要里程碑 —— 程式員負責「何時可能釋放」,配置器負責「確保最終釋放」。