選擇合適的分配方法
請依照以下指引選擇適合您情境的記憶體配置 API:
| Scenario | 推薦的 API | Notes |
|---|---|---|
| 通用 C++ 配置 | new / std::make_unique / std::make_shared |
這是 C++ 程式碼的預設選擇。 內部使用 CRT 堆疊。 RAII 確保自動清理。 |
| 通用 C 配置 | malloc / calloc / realloc |
C 程式碼的預設選項。 跨平台可攜式。 |
| 配置大於 ~1 MB 或需要頁面層級控制 | 虛擬阿洛克 | 以頁面細度(通常為 4 KB)分配。 用於保留具有特定保護屬性(PAGE_READWRITE、等 PAGE_EXECUTE_READ)的大位址範圍、保護頁或記憶體。 |
| 許多帶有自訂控制的小配置(例如池分配器) | HeapAlloc / 堆疊創造 | 建立一個私有堆積用於隔離或序列化控制。 僅在堆積完全是單執行緒時使用 HEAP_NO_SERIALIZE 。 |
| COM 互通性(編組記憶體) | CoTaskMemAlloc | 當記憶跨越 COM 公寓邊界時,必須使用。 MIDL 產生的存根使用 CoTaskMemAlloc/CoTaskMemFree。 |
| 使用可移動記憶體的舊有程式碼 | 全球阿洛克 / LocalAlloc | 避免使用新程式碼。 這些工具比 HeapAlloc 增加開銷,主要為了向下相容剪貼簿操作及某些需要它們的 Win32 API。 |
Important
配對配置與釋放功能時,務必正確正確。 分配到 的 HeapAlloc 記憶體必須以 HeapFree — 不是 free() 或 LocalFree來釋放。 混合分配/釋放家庭會導致難以診斷的堆積腐化。
Note
VirtualAlloc 與 HeapAlloc:VirtualAlloc 以頁面細度運作(最低 4 KB,預留對齊至 SYSTEM_INFO.dwAllocationGranularity,通常為 64 KB)。 將許多小型物件分配到 VirtualAlloc 會佔據位址空間。 使用 HeapAlloc (或 malloc/new) 來進行小且頻繁的分配。 當你需要保留大型位址區域、控制頁面保護或實作自訂配置器時,請使用 VirtualAlloc。
詳細比較
以下是各種記憶體分配方法的簡要比較:
雖然 GlobalAlloc、 LocalAlloc 和 HeapAlloc 函式最終會從同一堆積分配記憶體,但各自提供略有不同的功能。 例如,當無法分配記憶體時, HeapAlloc 可以被指示提出例外,這是 LocalAlloc 所沒有的功能。 LocalAlloc 支援分配句柄,允許透過重新配置移動底層記憶體而不改變句柄值,這是 HeapAlloc 所沒有的功能。
從 32 位元 Windows 開始,GlobalAlloc 和 LocalAlloc 以包裝函式實作,透過程序預設堆積的句柄呼叫 HeapAlloc。 因此, GlobalAlloc 和 LocalAlloc 的開銷比 HeapAlloc 更大。
由於不同的堆積配置器透過不同的機制提供獨特的功能,你必須用正確的功能來釋放記憶體。 例如,使用 HeapAlloc 配置的記憶體必須以 HeapFree 釋放,而非 LocalFree 或 GlobalFree。 使用 GlobalAlloc 或 LocalAlloc 配置的記憶體必須透過查詢、驗證,並以相應的全域或本地函式釋放。
VirtualAlloc 函式允許你指定額外的記憶體配置選項。 然而,其配置採用頁面細緻度,因此使用 VirtualAlloc 可能會導致記憶體使用量增加。
malloc 函數的缺點是依賴執行時間。 新運算子的缺點是依賴編譯器且依賴語言。
CoTaskMemAlloc 函式的優點是能在 C、C++ 或 Visual Basic 中運作良好。 它也是 COM 應用程式中唯一共享記憶體的方式,因為 MIDL 使用 CoTaskMemAlloc 和 CoTaskMemFree 來編組記憶體。
Examples
相關主題