Porównywanie metod alokacji pamięci

Wybieranie właściwej metody alokacji

Skorzystaj z poniższych wskazówek, aby wybrać odpowiedni interfejs API alokacji pamięci dla danego scenariusza:

Scenario Zalecany interfejs API Notatki
Alokacje języka C++ ogólnego przeznaczenia new / std::make_unique / std::make_shared Domyślny wybór kodu C++. Używa sterty CRT wewnętrznie. RAII zapewnia automatyczne czyszczenie.
Alokacje języka C ogólnego przeznaczenia malloc / calloc / realloc Domyślny wybór kodu C. Przenośne na różnych platformach.
Alokacje większe niż ok. 1 MB lub wymagające kontroli na poziomie strony VirtualAlloc Przydziela stopień szczegółowości strony (zazwyczaj 4 KB). Służy do rezerwowania dużych zakresów adresów, stron ochrony lub pamięci z określonymi atrybutami ochrony (PAGE_READWRITE, PAGE_EXECUTE_READitp.).
Wiele małych alokacji z kontrolką niestandardową (np. alokator puli) Heapalloc / StertaTworzenie Utwórz prywatną stertę na potrzeby izolacji lub kontrolki serializacji. Należy używać HEAP_NO_SERIALIZE tylko wtedy, gdy sterta jest wyłącznie jednowątkowa.
Międzyoperajności MODELU COM (pamięć marshaled) Cotaskmemalloc Wymagane, gdy pamięć przekracza granice mieszkania COM. Wycinki generowane przez midL używają coTaskMemAlloc/CoTaskMemFree.
Starszy kod korzystający z pamięci z możliwością przenoszenia GlobalAlloc / LocalAlloc Unikaj w przypadku nowego kodu. Te funkcje dodają obciążenie stosAlloc i istnieją przede wszystkim w celu zapewnienia zgodności z poprzednimi wersjami operacji schowka i niektórych interfejsów API Win32, które ich wymagają.

Ważna

Zawsze paruj funkcje alokacji i cofania przydziału. Pamięć przydzielona za pomocą HeapAlloc polecenia musi zostać zwolniona z wartością HeapFree — nie free() lub LocalFree. Mieszanie rodzin alokacji/ deallocation powoduje uszkodzenie sterty, które jest trudne do zdiagnozowania.

Note

VirtualAlloc vs HeapAlloc: VirtualAlloc działa na poziomie szczegółowości strony (co najmniej 4 KB, rezerwacje dostosowane do SYSTEM_INFO.dwAllocationGranularity, zazwyczaj 64 KB). Przydzielanie wielu małych obiektów za pomocą przestrzeni adresowej VirtualAlloc. Użyj metody HeapAlloc (lub malloc/new) w przypadku małych, częstych alokacji. Użyj polecenia VirtualAlloc, jeśli musisz zarezerwować duże regiony adresów, kontrolować ochronę strony lub implementować niestandardowe alokatory.

Szczegółowe porównanie

Poniżej przedstawiono krótkie porównanie różnych metod alokacji pamięci:

Mimo że funkcje GlobalAlloc, LocalAlloc i HeapAlloc ostatecznie przydzielają pamięć z tej samej sterty, każda z nich zapewnia nieco inny zestaw funkcji. Na przykład polecenie HeapAlloc można poinstruować, aby zgłosić wyjątek, jeśli nie można przydzielić pamięci, możliwość niedostępna w przypadku obiektu LocalAlloc. Funkcja LocalAlloc obsługuje alokację dojść, które zezwalają na przenoszenie pamięci bazowej za pomocą lokalizacji rzeczywistej bez zmieniania wartości dojścia, a funkcja nie jest dostępna w przypadku obiektu HeapAlloc.

Począwszy od 32-bitowych Windows, globalAlloc i LocalAlloc są implementowane jako funkcje otoki, które nazywają HeapAlloc przy użyciu uchwytu do domyślnej sterty procesu. W związku z tym wartości GlobalAlloc i LocalAlloc mają większe obciążenie niż HeapAlloc.

Ponieważ różne alokatory stert zapewniają charakterystyczne funkcje przy użyciu różnych mechanizmów, należy zwolnić pamięć z poprawną funkcją. Na przykład pamięć przydzielona za pomocą polecenia HeapAlloc musi zostać zwolniona z aplikacją HeapFree , a nie LocalFree lub GlobalFree. Pamięć przydzielona za pomocą obiektu GlobalAlloc lub LocalAlloc musi być odpytywane, weryfikowane i zwalniane z odpowiednią funkcją globalną lub lokalną.

Funkcja VirtualAlloc umożliwia określenie dodatkowych opcji alokacji pamięci. Jednak jej alokacje używają stopnia szczegółowości strony, więc użycie obiektu VirtualAlloc może spowodować większe użycie pamięci.

Funkcja malloc ma wadę zależną od czasu wykonywania. Nowy operator ma wadę zależną od kompilatora i zależną od języka.

Funkcja CoTaskMemAlloc ma zaletę pracy w języku C, C++lub Visual Basic. Jest to również jedyny sposób udostępniania pamięci w aplikacji opartej na modelu COM, ponieważ MIDL używa coTaskMemAlloc i CoTaskMemFree do marshalingu pamięci.

Examples

Funkcje globalne i lokalne

Funkcje stert

Funkcje pamięci wirtualnej