STL allocator 內存管理機制全解析
allocator 封裝了標準庫的內存管理,所有容器、string、算法、部分 iostream 均通過它分配/釋放內存。容器模板第二參數指定 allocator 類型,默認 std::allocator<T>。
GCC 4.8 實現的主要 allocator
1. __gnu_cxx::new_allocator(默認)
- 直接包裝
::operator new / operator delete。
- 無內存池,每次分配直接向系統請求。
- 「內存未回收」通常是 libc 的緩存未歸還 OS,非 STL 問題。
2. __gnu_cxx::malloc_allocator
- 直接包裝
malloc / free。
- 用法:
vector<int, __gnu_cxx::malloc_allocator<int>> v;
3. __gnu_cxx::array_allocator
- 使用預分配的固定內存塊,
_M_array 指向塊起始,_M_used 記錄偏移。
- 分配極快(指針移動),但超出塊大小拋出異常。適合已知最大內存、追求極致性能場景。
4. __gnu_cxx::debug_allocator
- 包裝任意 allocator,分配時額外存儲請求大小,釋放時校驗,檢測內存越界/洩漏。
- 調試用,有額外空間開銷。
5. __pool_alloc (舊版默認,SGI STL 風格)
- 帶內存池:>128 bytes 直接
operator new;≤128 bytes 從 free list 取,按 8 bytes 對齊分級(16 個桶)。
- 內存不歸還 OS,程序結束時釋放。減少碎片、提高小塊分配速度。
- 侯捷《STL源碼剖析》第二章詳細講解。
如何選擇?
- 一般情況:默認
new_allocator 即可。
- 需與 C 接口交互:
malloc_allocator。
- 高性能、固定內存上限:
array_allocator。
- 調試內存錯誤:
debug_allocator 包裝目標 allocator。
- 大量小對象、關注碎片:舊版
__pool_alloc 或自定義池。
參考資料
GCC 官方手冊:Memory Management