VirtualFree 函数 (memoryapi.h)

释放、取消提交或释放和取消提交调用进程的虚拟地址空间中的页面区域。

若要释放 VirtualAllocEx 函数在另一个进程中分配的内存,请使用 VirtualFreeEx 函数。

语法

BOOL VirtualFree(
  [in] LPVOID lpAddress,
  [in] SIZE_T dwSize,
  [in] DWORD  dwFreeType
);

参数

[in] lpAddress

指向要释放的页区域的基址的指针。

如果 dwFreeType 参数 MEM_RELEASE,则此参数必须是保留页面区域时 VirtualAlloc 函数返回的基址。

[in] dwSize

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

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

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

[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。

注解

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

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

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

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

VirtualFree 函数可用于内存的 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

另请参阅

内存管理函数

虚拟内存函数

VirtualFreeEx

VBS enclave 中可用的 Vertdll API