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