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标志。
  • *BaseAddressNtAllocateVirtualMemory 在保留区域时返回的基址。
  • *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 本机系统服务例程的 NtXxxZwXxx 版本在处理和解释输入参数的方式上的行为可能有所不同。 有关例程的 NtXxxZwXxx 版本之间的关系的详细信息,请参阅 使用本机系统服务例程的 Nt 和 Zw 版本

要求

要求
最低受支持的客户端 Windows 2000
目标平台 通用
标头 ntifs.h (包括 Ntifs.h、Fltkernel.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL
DDI 符合性规则 HwStorPortProhibitedDDI、PowerIrpDDis

另请参阅

NtAllocateVirtualMemory