Функция VirtualAllocExNuma (memoryapi.h)

Резервирует, фиксирует или изменяет состояние области памяти в виртуальном адресном пространстве указанного процесса и задает узел NUMA для физической памяти.

Синтаксис

LPVOID VirtualAllocExNuma(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect,
  [in]           DWORD  nndPreferred
);

Параметры

[in] hProcess

Дескриптор процесса. Функция выделяет память в пределах виртуального адресного пространства этого процесса.

Дескриптор должен иметь право доступа PROCESS_VM_OPERATION . Дополнительные сведения см. в разделе Управление правами на доступ и безопасность процесса.

[in, optional] lpAddress

Указатель, указывающий требуемый начальный адрес для области страниц, которую вы хотите выделить.

Если вы резервируете память, функция округляет этот адрес до ближайшего, кратного степени детализации выделения.

Если вы фиксируете память, которая уже зарезервирована, функция округляет этот адрес до ближайшей границы страницы. Чтобы определить размер страницы и степень детализации выделения на главном компьютере, используйте функцию GetSystemInfo .

Если lpAddress имеет значение NULL, функция определяет, где следует выделить регион.

[in] dwSize

Размер выделенной области памяти в байтах.

Если lpAddress имеет значение NULL, функция округляет dwSize до следующей границы страницы.

Если lpAddress не равно NULL, функция выделяет все страницы, содержащие один или несколько байтов в диапазоне от lpAddress до (lpAddress+dwSize). Это означает, например, что 2-байтовой диапазон, который граничит с границей страницы, приводит к тому, что функция выделяет обе страницы.

[in] flAllocationType

Тип выделения памяти. Этот параметр должен содержать одно из следующих значений.

Значение Значение
MEM_COMMIT
0x00001000
Выделяет расходы на память (из общего размера памяти и файлов подкачки на диске) для указанных зарезервированных страниц памяти. Функция также гарантирует, что при первоначальном обращении вызывающего объекта к памяти содержимое будет равно нулю. Фактические физические страницы не выделяются до тех пор, пока не будут доступны виртуальные адреса.

Чтобы зарезервировать и зафиксировать страницы за один шаг, вызовите функцию с MEM_COMMIT | MEM_RESERVEпомощью .

Попытка зафиксировать определенный диапазон адресов путем указания MEM_COMMIT без MEM_RESERVE и lpAddress, отличного от NULL, завершается ошибкой, если весь диапазон уже не зарезервирован. Полученный код ошибки ERROR_INVALID_ADDRESS.

Попытка зафиксировать уже зафиксированную страницу не приводит к сбою функции. Это означает, что вы можете фиксировать страницы без предварительного определения текущего состояния обязательств каждой страницы.

MEM_RESERVE
0x00002000
Резервирует диапазон виртуального адресного пространства процесса, не выделяя фактическое физическое хранилище в памяти или в файле подкачки на диске.

Зарезервированные страницы фиксируются путем повторного вызова функции с MEM_COMMIT. Чтобы зарезервировать и зафиксировать страницы за один шаг, вызовите функцию с MEM_COMMIT | MEM_RESERVEпомощью .

Другие функции выделения памяти, такие как malloc и LocalAlloc, не могут использовать зарезервированную память, пока она не будет освобождена.

MEM_RESET
0x00080000
Указывает, что данные в диапазоне памяти, заданном lpAddress и dwSize , больше не представляют интереса. Страницы не должны считываться из файла подкачки или записываться в нее. Однако блок памяти будет использоваться позже, поэтому он не должен быть списан. Это значение нельзя использовать с каким-либо другим значением.

Использование этого значения не гарантирует, что диапазон, с которым работает MEM_RESET , будет содержать нули. Если вы хотите, чтобы диапазон содержал нули, удалите память, а затем снова зафиксируете ее.

При использовании MEM_RESET функция игнорирует значение fProtect. Однако необходимо по-прежнему задать для параметра fProtect допустимое значение защиты, например PAGE_NOACCESS.

Функция возвращает ошибку, если используется MEM_RESET и диапазон памяти сопоставлен с файлом. Общее представление допустимо только в том случае, если оно сопоставлено с файлом подкачки.

MEM_RESET_UNDO
0x1000000
MEM_RESET_UNDO следует вызывать только для диапазона адресов, к которому MEM_RESET были успешно применены ранее. Оно указывает, что данные в указанном диапазоне памяти, заданном lpAddress и dwSize , представляют интерес для вызывающего объекта и пытаются обратить вспять эффекты MEM_RESET. Если функция выполнена успешно, это означает, что все данные в указанном диапазоне адресов остаются без изменений. Если функция завершается сбоем, по крайней мере некоторые данные в диапазоне адресов были заменены нулями.

Это значение нельзя использовать с каким-либо другим значением. Если MEM_RESET_UNDO вызывается в диапазоне адресов, который не был MEM_RESET ранее, поведение не определено. При указании MEM_RESET функция VirtualAllocExNuma игнорирует значение flProtect. Однако необходимо по-прежнему задать для flProtect допустимое значение защиты, например PAGE_NOACCESS.

Windows Server 2008 R2, Windows 7, Windows Server 2008 и Windows Vista: Флаг MEM_RESET_UNDO не поддерживается до Windows 8 и Windows Server 2012.

 

Этот параметр также может указывать следующие значения, как указано.

Значение Значение
MEM_LARGE_PAGES
0x20000000
Выделяет память с помощью поддержки больших страниц.

Размер и выравнивание должны быть кратными минимуму большой страницы. Чтобы получить это значение, используйте функцию GetLargePageMinimum .

Если указать это значение, необходимо также указать MEM_RESERVE и MEM_COMMIT.

MEM_PHYSICAL
0x00400000
Резервирует диапазон адресов, который можно использовать для сопоставления страниц расширений окон адресов (AWE).

Это значение должно использоваться с MEM_RESERVE и никакими другими значениями.

MEM_TOP_DOWN
0x00100000
Выделяет память по максимально возможному адресу.

[in] flProtect

Защита памяти для области выделенных страниц. Если страницы фиксируются, можно указать любую из констант защиты памяти.

Атрибуты защиты, указанные при защите страницы, не могут конфликтовать с атрибутами, указанными при выделении страницы.

[in] nndPreferred

Узел NUMA, где должна находиться физическая память.

Используется только при выделении нового региона va (зафиксированного или зарезервированного). В противном случае этот параметр игнорируется, если API используется для фиксации страниц в регионе, который уже существует.

Возвращаемое значение

Если функция выполнена успешно, возвращаемое значение является базовым адресом выделенной области страниц.

Если функция завершается сбоем, возвращается значение NULL. Дополнительные сведения об ошибке можно получить, вызвав GetLastError.

Комментарии

Каждая страница имеет связанное состояние страницы. Функция VirtualAllocExNuma может выполнять следующие операции:

  • Фиксация области зарезервированных страниц
  • Зарезервировать регион бесплатных страниц
  • Одновременное резервирование и фиксация области бесплатных страниц

VirtualAllocExNuma не удается зарезервировать зарезервированную страницу. Он может зафиксировать уже зафиксированную страницу. Это означает, что вы можете зафиксировать диапазон страниц, независимо от того, были ли они уже зафиксированы, и функция не завершится ошибкой.

Вы можете использовать VirtualAllocExNuma , чтобы зарезервировать блок страниц, а затем выполнить дополнительные вызовы к VirtualAllocExNuma для фиксации отдельных страниц из зарезервированного блока. Это позволяет процессу зарезервировать диапазон своего виртуального адресного пространства без использования физического хранилища до тех пор, пока оно не потребуется.

Если параметр lpAddress не равен NULL, функция использует параметры lpAddress и dwSize для вычисления области выделенных страниц. Текущее состояние всего диапазона страниц должно быть совместимо с типом выделения, заданным параметром flAllocationType . В противном случае функция завершается сбоем, и ни одна из страниц не выделяется. Это требование совместимости не исключает фиксацию уже зафиксированной страницы; см. предыдущий список.

Так как VirtualAllocExNuma не выделяет физические страницы, она будет успешно выполнена независимо от того, доступны ли страницы на этом узле или в другом месте в системе. Физические страницы выделяются по требованию. Если на предпочтительном узле не хватает страниц, диспетчер памяти будет использовать страницы из других узлов. Если память выкачена на страницу, то при ее возврате используется тот же процесс.

Чтобы выполнить динамически созданный код, используйте VirtualAllocExNuma для выделения памяти и функцию VirtualProtectEx , чтобы предоставить доступ к PAGE_EXECUTE .

Функцию VirtualAllocExNuma можно использовать для резервирования области памяти AWE в виртуальном адресном пространстве указанного процесса. Затем эту область памяти можно использовать для сопоставления физических страниц с виртуальной памятью и из нее в соответствии с требованиями приложения. Значения MEM_PHYSICAL и MEM_RESERVE должны быть заданы в параметре AllocationType . Значение MEM_COMMIT задавать нельзя. Для защиты страницы необходимо задать значение PAGE_READWRITE.

Функция VirtualFreeEx может высвободить зафиксированную страницу, освободить хранилище страницы или одновременно снять и освободить зафиксированную страницу. Он также может освободить зарезервированную страницу, сделав ее бесплатной.

Чтобы скомпилировать приложение, использующее эту функцию, определите _WIN32_WINNT как 0x0600 или более поздней версии.

Примеры

Пример см. в разделе Выделение памяти из узла NUMA.

Требования

   
Минимальная версия клиента Windows Vista [только классические приложения]
Минимальная версия сервера Windows Server 2008 [только классические приложения]
Целевая платформа Windows
Header memoryapi.h (включая Windows.h, Memoryapi.h)
Библиотека onecore.lib
DLL Kernel32.dll

См. также

Функции управления памятью

Поддержка NUMA

Функции виртуальной памяти

VirtualAllocEx

VirtualFreeEx

VirtualLock

VirtualProtect

VirtualQuery