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

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

С помощью этой функции можно: для новых выделений указать диапазон виртуального адресного пространства и ограничение на выравнивание по возможности 2; укажите произвольное число расширенных параметров; укажите предпочтительный узел NUMA для физической памяти в качестве расширенного параметра; и укажите операцию заполнителя (в частности, замену).

Чтобы указать узел NUMA, см. параметр ExtendedParameters .

Синтаксис

PVOID VirtualAlloc2FromApp(
  [in, optional]      HANDLE                 Process,
  [in, optional]      PVOID                  BaseAddress,
  [in]                SIZE_T                 Size,
  [in]                ULONG                  AllocationType,
  [in]                ULONG                  PageProtection,
  [in, out, optional] MEM_EXTENDED_PARAMETER *ExtendedParameters,
  [in]                ULONG                  ParameterCount
);

Параметры

[in, optional] Process

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

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

[in, optional] BaseAddress

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

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

Если BaseAddress не имеет значение NULL, то любая предоставленная MEM_ADDRESS_REQUIREMENTS структура должна состоять из всех нулей, а базовый адрес должен быть кратным степени детализации распределения системы. Чтобы определить степень детализации выделения, используйте функцию GetSystemInfo .

[in] Size

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

Размер всегда должен быть кратным размеру страницы.

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

[in] AllocationType

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

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

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

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

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

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

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

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

MEM_REPLACE_PLACEHOLDER
0x00004000
Заменяет заполнитель обычным частным выделением. Поддерживаются только представления разделов с поддержкой данных и pf (без изображений, физической памяти и т. д.). При замене заполнителя BaseAddress и Size должны точно соответствовать значениям заполнителя, а любая предоставленная MEM_ADDRESS_REQUIREMENTS структура должна состоять из всех нулей.

После замены заполнителя частным выделением, чтобы освободить это выделение обратно в заполнитель, см. параметр dwFreeTypevirtualFree и VirtualFreeEx.

Заполнитель — это тип зарезервированной области памяти.

MEM_RESERVE_PLACEHOLDER
0x00040000
Чтобы создать заполнитель, вызовите VirtualAlloc2 с MEM_RESERVE | MEM_RESERVE_PLACEHOLDER параметром PageProtectionPAGE_NOACCESS. Сведения о том, как освободить, разделить или объединить заполнитель, см. в параметрах dwFreeTypeдля VirtualFree и VirtualFreeEx.

Заполнитель — это тип зарезервированной области памяти.

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

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

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

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

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

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

 

Этот параметр также может указывать указанные ниже значения.

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

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

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

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

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

MEM_TOP_DOWN
0x00100000
Выделяет память по максимально возможному адресу. Это может быть медленнее, чем обычное выделение, особенно при наличии большого количества выделений.
MEM_WRITE_WATCH
0x00200000
Позволяет системе отслеживать страницы, на которые записываются данные в выделенном регионе. Если указать это значение, необходимо также указать MEM_RESERVE.

Чтобы получить адреса страниц, на которые были записаны с момента выделения региона или сброса состояния отслеживания записи, вызовите функцию GetWriteWatch . Чтобы сбросить состояние отслеживания записи, вызовите Метод GetWriteWatch или ResetWriteWatch. Функция отслеживания записи остается включенной для области памяти до освобождения региона.

[in] PageProtection

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

  • PAGE_EXECUTE
  • PAGE_EXECUTE_READ
  • PAGE_EXECUTE_READWRITE
  • PAGE_EXECUTE_WRITECOPY

[in, out, optional] ExtendedParameters

Необязательный указатель на один или несколько расширенных параметров типа MEM_EXTENDED_PARAMETER. Каждое из этих значений расширенных параметров может иметь поле Typeлибо MemExtendedParameterAddressRequirements , либо MemExtendedParameterNumaNode. Если расширенный параметр MemExtendedParameterNumaNode не указан, поведение будет таким же, как и для функций VirtualAlloc/MapViewOfFile (то есть предпочтительный узел NUMA для физических страниц определяется на основе идеального процессора потока, который сначала обращается к памяти).

[in] ParameterCount

Количество расширенных параметров, на которые указывает ExtendedParameters.

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

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

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

Комментарии

Этот API помогает поддерживать высокопроизводительные игры и серверные приложения, которые предъявляют особые требования к управлению виртуальным адресным пространством. Например, сопоставление памяти поверх ранее зарезервированной области; это полезно для реализации кольцевого буфера с автоматическим переносом. И выделение памяти с определенным выравниванием; например, чтобы позволить приложению фиксировать большие или огромные сопоставленные регионы по запросу.

Вы можете вызывать Virtual2AllocFromApp из приложений Магазина Windows с возможностями JIT для использования функций JIT. Чтобы использовать возможности JIT, приложение должно включать возможность codeGeneration в файл манифеста приложения.

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

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

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

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

Virtual2AllocFromApp не позволяет создавать исполняемые страницы.

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

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

При создании региона, который будет исполняемым, вызывающая программа несет ответственность за обеспечение когерентности кэша с помощью соответствующего вызова FlushInstructionCache после установки кода. В противном случае попытки выполнить код из новой исполняемой области могут привести к непредсказуемым результатам.

Примеры

Примеры кода см. в разделе Virtual2Alloc.

Требования

Требование Значение
Минимальная версия клиента Windows 10 [только классические приложения]
Минимальная версия сервера Windows Server 2016 [только классические приложения]
Целевая платформа Windows
Header memoryapi.h (включая Windows.h)
Библиотека WindowsApp.lib
DLL Kernel32.dll

См. также

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

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

VirtualAlloc

VirtualAllocEx

VirtualFree

VirtualLock

VirtualProtectFromApp

VirtualQuery