VirtualFreeEx 函数 (memoryapi.h)

释放、取消提交或释放和取消提交指定进程的虚拟地址空间中的内存区域。

语法

BOOL VirtualFreeEx(
  [in] HANDLE hProcess,
  [in] LPVOID lpAddress,
  [in] SIZE_T dwSize,
  [in] DWORD  dwFreeType
);

参数

[in] hProcess

进程的句柄。 函数释放进程的虚拟地址空间中的内存。

句柄必须具有 PROCESS_VM_OPERATION 访问权限。 有关详细信息,请参阅 进程安全和访问权限

[in] lpAddress

指向要释放的内存区域的起始地址的指针。

如果 dwFreeType 参数 MEM_RELEASE,则 lpAddress 必须是保留区域时 VirtualAllocEx 函数返回的基址。

[in] dwSize

要释放的内存区域的大小(以字节为单位)。

如果 dwFreeType 参数 MEM_RELEASE,则 dwSize 必须为 0 (零) 。 函数释放在 对 VirtualAllocEx 的初始分配调用中保留的整个区域。

如果 dwFreeTypeMEM_DECOMMIT,则函数将取消提交包含从 lpAddress 参数到 (lpAddress+dwSize)范围内的一个或多个字节的所有内存页。 例如,这意味着跨越页边界的 2 字节内存区域会导致两个页面都解除提交。 如果 lpAddressVirtualAllocEx 返回的基址,而 dwSize 为 0 (零) ,则函数将取消提交 VirtualAllocEx 分配的整个区域。 之后,整个区域将处于保留状态。

[in] dwFreeType

自由操作的类型。 此参数须为下列值之一。

含义
MEM_DECOMMIT
0x00004000
取消提交已提交页面的指定区域。 操作后,页面将处于保留状态。

如果尝试取消提交未提交的页面,函数不会失败。 这意味着,无需先确定当前承诺状态,即可取消提交一系列页面。

lpAddress 参数提供 enclave 的基址时,不支持MEM_DECOMMIT值。 对于不支持动态内存管理 ((即 SGX1) )的 enclave 也是如此。 SGX2 enclave 允许MEM_DECOMMIT enclave 中的任意位置。

MEM_RELEASE
0x00008000
释放指定的页面区域或占位符 (占位符,释放地址空间并可用于) 的其他分配。 在执行该操作之后,这些页面将处于可用状态。

如果指定此值, dwSize 必须为 0 (零) ,并且 lpAddress 必须指向保留区域时 VirtualAlloc 函数返回的基址。 如果未满足上述任一条件,该函数将失败。

如果当前已提交区域中的任何页面,该函数将首先取消提交,然后释放它们。

如果尝试释放处于不同状态(一些保留和一些已提交)的页面,函数不会失败。 这意味着,无需首先确定当前承诺状态即可发布一系列页面。

使用 MEM_RELEASE 时,此参数还可以指定以下值之一。

含义
MEM_COALESCE_PLACEHOLDERS
0x00000001
若要合并两个相邻占位符,请指定 MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS。 合并占位符时, lpAddressdwSize 必须与要合并的占位符的总体范围完全匹配。
MEM_PRESERVE_PLACEHOLDER
0x00000002
使用 VirtualAlloc2 或Virtual2AllocFromApp) 将占位符替换为专用分配后,将分配释放回占位符 (。

若要将占位符拆分为两个占位符,请指定 MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER

返回值

如果函数成功,则返回值为非零值。

如果函数失败,则返回值为 0(零)。 要获得更多的错误信息,请调用 GetLastError。

注解

进程虚拟地址空间中的每个内存页都有一个 页状态VirtualFreeEx 函数可以取消提交处于不同状态(一些已提交和一些未提交)的页面范围。 这意味着,无需首先确定每个页面的当前承诺状态,即可取消提交一系列页面。 取消提交页面会释放其物理存储,无论是在内存中还是在磁盘上的分页文件中。

如果已取消提交但未释放页面,则其状态将更改为保留。 随后,可以调用 VirtualAllocEx 来提交它,或 调用 VirtualFreeEx 来释放它。 尝试读取或写入保留页会导致访问冲突异常。

VirtualFreeEx 函数可以释放处于不同状态(一些保留和一些已提交)的一系列页面。 这意味着,无需首先确定每个页面的当前承诺状态,即可发布一系列页面。 必须同时释放 最初由 VirtualAllocEx 保留的整个页面范围。

如果释放页面,则其状态将更改为释放,并且可用于后续分配操作。 释放或取消提交内存后,永远无法再次引用内存。 该内存中可能已存在的任何信息将永远消失。 尝试读取或写入免费页面会导致访问冲突异常。 如果需要保留信息,请不要取消提交或释放包含该信息的内存。

VirtualFreeEx 函数可用于内存的 AWE 区域,并在释放地址空间时使该区域中的任何物理页映射失效。 但是,不会删除物理页,应用程序可以使用它们。 应用程序必须显式调用 FreeUserPhysicalPages 以释放物理页面。 进程终止后,会自动清理所有资源。

Windows 10版本 1709 及更高版本以及Windows 11:若要在使用完 enclave 后将其删除,请调用 DeleteEnclave。 无法通过调用 VirtualFree 或 VirtualFreeEx 函数删除 VBS enclave。 仍可通过调用 VirtualFree 或 VirtualFreeEx 删除 SGX enclave

Windows 10版本 1507、Windows 10、版本 1511、Windows 10、版本 1607 和 Windows 10 版本 1703:若要在使用完 enclave 后删除它,请调用 VirtualFreeVirtualFreeEx 函数并指定以下值:

  • lpAddress 参数的 enclave 基址。
  • 0 表示 dwSize 参数。
  • dwFreeType 参数的MEM_RELEASE

要求

要求
最低受支持的客户端 Windows XP [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 memoryapi.h (包括 Windows.h、Memoryapi.h)
Library onecore.lib
DLL Kernel32.dll

另请参阅

内存管理函数

虚拟内存函数

VirtualAllocEx