NtFreeVirtualMemory 函数 (ntifs.h)
NtFreeVirtualMemory 例程发布和/或取消提交,指定进程的虚拟地址空间中的页面区域。
语法
__kernel_entry NTSYSCALLAPI NTSTATUS NtFreeVirtualMemory(
[in] HANDLE ProcessHandle,
[in, out] PVOID *BaseAddress,
[in, out] PSIZE_T RegionSize,
[in] ULONG FreeType
);
参数
[in] ProcessHandle
要释放的页面所在的上下文的进程句柄。 使用 Ntddk.h 中定义的 NtCurrentProcess 宏指定当前进程。
[in, out] BaseAddress
指向变量的指针,该变量将接收页面释放区域的基虚拟地址。
如果在 FreeType 参数中设置了MEM_RELEASE标志, *BaseAddress 必须是保留区域时 NtAllocateVirtualMemory 返回的基址。
[in, out] RegionSize
指向变量的指针,该变量将接收页面释放区域的实际大小(以字节为单位)。 例程将此变量的初始值舍入到下一个主机页大小边界,并将舍入值写回此变量。
如果在 *FreeType 中设置了MEM_RELEASE标志, *RegionSize 必须为零。 NtFreeVirtualMemory 释放在 NtAllocateVirtualMemory 的初始分配调用中保留的整个区域。
如果在 *FreeType 中设置了MEM_DECOMMIT标志, 则 NtFreeVirtualMemory 将取消提交包含一个或多个字节的所有内存页,范围从 *BaseAddress 到 (*BaseAddress + *RegionSize) 。 这意味着,例如,如果内存的两字节区域跨页边界,则两个页面都将取消提交。
NtFreeVirtualMemory 取消提交 NtAllocateVirtualMemory 保留的整个区域。 如果满足以下三个条件,则整个区域将进入保留状态:
- 设置MEM_DECOMMIT标志。
- *BaseAddress 是 NtAllocateVirtualMemory 在保留区域时返回的基址。
- *RegionSize 为零。
[in] FreeType
一个位掩码,其中包含描述 NtFreeVirtualMemory 将对指定页面区域执行的自由操作类型的标志。 下表列出了可能的值。
标志 | 含义 |
---|---|
MEM_DECOMMIT | NtFreeVirtualMemory 将取消提交指定的页面区域。 页面进入保留状态。 如果尝试取消提交未提交的页面,NtFreeVirtualMemory 不会失败。 这意味着可以取消提交一系列页面,而无需先确定页面的当前承诺状态。 |
MEM_RELEASE | NtFreeVirtualMemory 将释放指定的页面区域。 页面进入空闲状态。 如果指定此标志, 则 RegionSize 必须为零, BaseAddress 必须指向保留区域时 NtAllocateVirtualMemory 返回的基址。 如果未满足上述任一条件,NtFreeVirtualMemory 将失败。 如果当前已提交区域中的任何页面, 则 NtFreeVirtualMemory 先取消提交,然后释放它们。 如果尝试释放处于不同状态(一些保留和一些已提交)的页面,NtFreeVirtualMemory 不会失败。 这意味着,无需先确定页面的当前承诺状态即可发布一系列页面。 |
返回值
NtFreeVirtualMemory 返回STATUS_SUCCESS或错误状态代码。 可能的错误状态代码包括以下内容。
返回代码 | 说明 |
---|---|
STATUS_ACCESS_DENIED | 进程已请求访问对象,但尚未被授予这些访问权限。 |
STATUS_INVALID_HANDLE | 指定了无效 的 ProcessHandle 值。 |
STATUS_OBJECT_TYPE_MISMATCH | 请求的操作所需的对象类型与请求中指定的对象类型不匹配。 |
注解
进程的虚拟地址空间中的每个页面都处于下表所述的三种状态之一。
状态 | 含义 |
---|---|
FREE | 页面既不提交也不保留。 进程无法访问该页面。 尝试从免费页面读取或写入会导致访问冲突异常。 可以使用 NtFreeVirtualMemory 将保留或提交的页面置于免费状态。 |
RESERVED | 该页是保留的。 地址范围不能由其他分配函数使用。 进程无法访问该页,并且没有与之关联的物理存储。 尝试从保留页读取或写入会导致访问冲突异常。 可以使用 NtFreeVirtualMemory 将提交的内存页置于保留状态,并将预留内存页置于可用状态。 |
承诺 | 已提交页面。 内存中或磁盘上分页文件中的物理存储为页面分配,访问由保护代码控制。 系统仅在第一次尝试从该页读取或写入该页时,初始化每个提交的页面并将其加载到物理内存中。 当进程终止时,系统会释放已提交页面的所有存储。 可以使用 NtAllocateVirtualMemory 将提交的内存页置于保留或可用状态。 |
NtFreeVirtualMemory 可以执行以下操作:
- 取消提交包含已提交或未提交的页面的区域。 此操作后,页面将处于保留状态。
- 释放保留页的区域。 在执行该操作之后,这些页面将处于可用状态。
- 取消提交并释放包含已提交或未提交的页面的区域。 在执行该操作之后,这些页面将处于可用状态。
NtFreeVirtualMemory 可以取消提交处于不同状态(一些已提交和一些未提交的)的一系列页面。 这意味着,无需先确定每个页面的当前承诺状态,即可取消提交一系列页面。 取消提交页面会释放其物理存储,无论是在内存中还是在磁盘上的分页文件中。
如果页面已取消提交但未释放,则其状态将更改为“保留”。 随后可以调用 NtAllocateVirtualMemory 来提交它,或 调用 NtFreeVirtualMemory 来释放它。 尝试从保留页读取或写入会导致访问冲突异常。
NtFreeVirtualMemory 可以发布处于不同状态(一些保留和一些已提交)的一系列页面。 这意味着,无需首先确定每个页面的当前承诺状态,即可发布一系列页面。 最初由 NtAllocateVirtualMemory 保留的整个页面范围必须同时发布。
如果发布页面,则其状态将更改为“释放”,并且可用于后续的分配操作。 释放或取消提交内存后,再也不能引用内存。 该内存中可能已存在的任何信息将永久消失。 尝试从免费页面读取或写入会导致访问冲突异常。 如果需要信息,请不要弃用或释放包含该信息的内存。
有关内核模式驱动程序的内存管理支持的详细信息,请参阅 Windows 驱动程序的内存管理。
注意
如果在用户模式下调用 NtFreeVirtualMemory 函数,则应使用名称“NtFreeVirtualMemory”而不是“ZwFreeVirtualMemory”。
对于来自内核模式驱动程序的调用,Windows 本机系统服务例程的 NtXxx 和 ZwXxx 版本在处理和解释输入参数的方式上的行为可能有所不同。 有关例程的 NtXxx 和 ZwXxx 版本之间的关系的详细信息,请参阅 使用本机系统服务例程的 Nt 和 Zw 版本。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 2000 |
目标平台 | 通用 |
标头 | ntifs.h (包括 Ntifs.h、Fltkernel.h) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL |
DDI 符合性规则 | HwStorPortProhibitedDDI、PowerIrpDDis |