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
内存分配的类型。 此参数必须包含以下值之一。
值 | 含义 |
---|---|
|
从指定保留内存页的磁盘) 的总内存大小和分页文件 (分配内存费用。 函数还保证当调用方稍后最初访问内存时,内容将为零。 除非实际访问虚拟地址,否则不会分配实际物理页面。
若要在一个步骤中保留和提交页面,请使用 调用 Virtual2AllocFromApp 除非已保留整个范围,否则尝试通过指定 MEM_COMMIT 而不指定 MEM_RESERVE 和非 NULLBaseAddress 来提交特定地址范围。 生成的错误代码ERROR_INVALID_ADDRESS。 尝试提交已提交的页面不会导致函数失败。 这意味着,无需先确定每个页面的当前承诺状态即可提交页面。 |
|
保留进程的虚拟地址空间范围,而无需在内存或磁盘上的分页文件中分配任何实际物理存储。
可以在后续调用 Virtual2AllocFromApp 函数时提交保留页。 若要在一个步骤中保留和提交页面,请使用 MEM_COMMIT MEM_RESERVE | 调用 Virtual2AllocFromApp。 其他内存分配函数(如 malloc 和 LocalAlloc)在释放内存之前,不能使用保留的内存范围。 |
|
将占位符替换为普通专用分配。 仅支持数据/pf 支持的分区视图, (无图像、物理内存等 ) 。 替换占位符时, BaseAddress 和 Size 必须完全匹配占位符,并且提供的任何 MEM_ADDRESS_REQUIREMENTS 结构都必须包含所有零。
将占位符替换为专用分配后,若要将该分配释放回占位符,请参阅 VirtualFree 和 VirtualFreeEx 的 dwFreeType 参数。 占位符是保留内存区域的一种类型。 |
|
若要创建占位符,请调用 VirtualAlloc2 ,并将 MEM_RESERVE | MEM_RESERVE_PLACEHOLDER PageProtection 设置为 PAGE_NOACCESS。 若要释放/拆分/合并占位符,请参阅 VirtualFree 和 VirtualFreeEx 的 dwFreeType 参数。
占位符是保留内存区域的一种类型。 |
|
指示 BaseAddress 和 Size 指定的内存范围中的数据不再感兴趣。 不应从分页文件读取或写入页面。 但是,内存块稍后将再次使用,因此不应取消提交。 此值不能与任何其他值一起使用。
使用此值并不能保证使用 MEM_RESET 操作的范围将包含零。 如果希望范围包含零,请取消提交内存,然后重新提交。 指定 MEM_RESET时, Virtual2AllocFromApp 函数会忽略 Protection 的值。 但是,仍必须将 “保护 ”设置为有效的保护值,例如 PAGE_NOACCESS。 如果使用 MEM_RESET并且内存范围映射到文件,则 Virtual2AllocFromApp 将返回错误。 仅当共享视图映射到分页文件时,才可接受该视图。 |
|
应 仅对之前成功应用MEM_RESET的地址范围调用 MEM_RESET_UNDO 。 它指示 由 BaseAddress 和 Size 指定的内存范围中的数据对调用方感兴趣,并尝试反转 MEM_RESET的影响。 如果该函数成功,则表示指定地址范围中的所有数据都保持不变。 如果函数失败,则至少将地址范围中的某些数据替换为零。
此值不能与任何其他值一起使用。 如果在之前未MEM_RESET的地址范围上调用MEM_RESET_UNDO,则行为未定义。 指定 MEM_RESET时, Virtual2AllocFromApp 函数会忽略 Protection 的值。 但是,仍必须将 “保护 ”设置为有效的保护值,例如 PAGE_NOACCESS。 |
此参数还可以按指示指定以下值。
值 | 含义 |
---|---|
|
使用 大页支持分配内存。
大小和对齐方式必须是大页最小值的倍数。 若要获取此值,请使用 GetLargePageMinimum 函数。 如果指定此值,还必须指定 MEM_RESERVE 和 MEM_COMMIT。 |
|
保留可用于将 地址窗口扩展 (AWE) 页映射的地址范围。
此值必须与 MEM_RESERVE 一起使用,不能与其他值一起使用。 |
|
在可能的最高地址分配内存。 这可能比常规分配慢,尤其是在有许多分配时。 |
|
使系统跟踪在分配区域中写入的页面。 如果指定此值,还必须指定 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类型的一个或多个扩展参数的可选指针。 每个扩展参数值本身都可以具有 MemExtendedParameterAddressRequirements 或 MemExtendedParameterNumaNode的 Type 字段。 如果未提供 MemExtendedParameterNumaNode 扩展参数,则行为与 VirtualAlloc/MapViewOfFile 函数 (相同,也就是说,物理页的首选 NUMA 节点是根据首先访问内存) 线程的理想处理器确定的。
[in] ParameterCount
ExtendedParameters 指向的扩展参数数。
返回值
如果函数成功,则返回值是已分配页区域的基址。
如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。
注解
此 API 有助于支持高性能游戏和服务器应用程序,这些应用程序在管理虚拟地址空间方面有特定要求。 例如,在以前保留的区域上映射内存;这对于实现自动环绕环缓冲区很有用。 并分配具有特定对齐方式的内存;例如,使应用程序能够按需提交大型/大型页面映射区域。
可以通过实时 (JIT) 功能从 Windows 应用商店应用调用 Virtual2AllocFromApp 以使用 JIT 功能。 应用必须在应用清单文件中包含 codeGeneration 功能才能使用 JIT 功能。
每个页面都有一个关联的 页状态。 Virtual2AllocFromApp 函数可以执行以下操作:
- 提交保留页的区域
- 保留可用页面区域
- 同时保留和提交可用页面区域
可以使用 Virtual2AllocFromApp 保留页面块,然后对 Virtual2AllocFromApp 进行其他调用,以提交保留块中的单个页面。 这使进程能够保留其虚拟地址空间的范围,而无需使用物理存储,直到需要为止。
如果 BaseAddress 参数不为 NULL,则该函数使用 BaseAddress 和 Size 参数来计算要分配的页面区域。 整个页面范围的当前状态必须与 AllocationType 参数指定的分配类型兼容。 否则,函数将失败,并且不会分配任何页面。 如前所述,此兼容性要求不排除提交已提交的页面。
Virtual2AllocFromApp 不允许创建可执行页面。
Virtual2AllocFromApp 函数可用于在指定进程的虚拟地址空间中保留地址窗口扩展 (AWE) 内存区域。 然后,可以使用此内存区域将物理页映射到虚拟内存中,以及根据应用程序的要求映射出虚拟内存。 必须在 AllocationType 参数中设置MEM_PHYSICAL和MEM_RESERVE值。 不得设置 MEM_COMMIT 值。 页面保护必须设置为 PAGE_READWRITE。
VirtualFree 函数可以取消提交已提交的页面、释放页面的存储,也可以同时取消提交和释放已提交的页面。 它还可以释放保留页,使其成为免费页面。
创建将可执行的区域时,调用程序负责在代码设置到位后,通过适当调用 FlushInstructionCache 来确保缓存一致性。 否则,尝试从新可执行区域执行代码可能会产生不可预知的结果。
示例
有关代码示例,请参阅 Virtual2Alloc。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 10 [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2016 [仅限桌面应用] |
目标平台 | Windows |
标头 | memoryapi.h (包括 Windows.h) |
Library | WindowsApp.lib |
DLL | Kernel32.dll |
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈