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 への初期割り当て呼び出しで予約されているリージョン全体を解放します。
dwFreeType がMEM_DECOMMITの場合、この関数は lpAddress パラメーターから の範囲の 1 つ以上のバイトを含むすべてのメモリ ページをコミット解除します(lpAddress+dwSize)
。 つまり、たとえば、ページ境界をまたぐ 2 バイトのメモリ領域により、両方のページがコミット解除されます。 lpAddress が VirtualAllocEx によって返されるベース アドレスで、dwSize が 0 (ゼロ) の場合、関数は VirtualAllocEx によって割り当てられたリージョン全体をデコミットします。 その後、リージョン全体が予約状態になります。
[in] dwFreeType
空き操作の種類。 このパラメーターには次のいずれかの値を指定する必要があります。
値 | 意味 |
---|---|
|
コミットされたページの指定された領域をデコミットします。 操作の後、ページは予約済みの状態になります。
コミットされていないページのコミットを解除しようとしても、関数は失敗しません。 つまり、現在のコミットメント状態を最初に決定することなく、ページの範囲をコミット解除できます。 lpAddress パラメーターがエンクレーブのベース アドレスを提供する場合、MEM_DECOMMIT値はサポートされません。 これは、動的メモリ管理 (つまり SGX1) をサポートしないエンクレーブに当てはまります。 SGX2 エンクレーブでは、エンクレーブ内の任意の場所にMEM_DECOMMITできます。 |
|
ページの指定した領域またはプレースホルダーを解放します (プレースホルダーの場合、アドレス空間は解放され、他の割り当てで使用できます)。 この操作の後、ページは空き状態になります。
この値を指定する場合、 dwSize は 0 (ゼロ) である必要があり、 lpAddress はリージョンの予約時に VirtualAlloc 関数によって返されるベース アドレスを指す必要があります。 この条件が両方とも満たされないと、エラーが発生します。 リージョン内のページが現在コミットされている場合、関数は最初にコミットを解除してから解放します。 異なる状態のページ (予約済みページとコミット済みページ) を解放しようとしても、関数は失敗しません。 つまり、現在のコミットメント状態を最初に決定することなく、ページの範囲を解放できます。 |
MEM_RELEASEを使用する場合、このパラメーターは次のいずれかの値を追加で指定できます。
値 | 意味 |
---|---|
|
隣接する 2 つのプレースホルダーを結合するには、 を指定します MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS 。 プレースホルダーを結合する場合、 lpAddress と dwSize は、マージするプレースホルダーの全体的な範囲と完全に一致する必要があります。
|
|
割り当てをプレースホルダーに解放します (プレースホルダーを VirtualAlloc2 または Virtual2AllocFromApp を使用してプライベート割り当てに置き換えた後)。
プレースホルダーを 2 つのプレースホルダーに分割するには、 を指定 |
戻り値
関数が成功した場合、戻り値は 0 以外の値になります。
関数が失敗した場合は、0 を返します。 詳細なエラー情報を得るには、GetLastError を呼び出します。
解説
プロセス仮想アドレス空間内のメモリの各ページには 、ページ状態があります。 VirtualFreeEx 関数を使用すると、さまざまな状態にあるページの範囲をコミット解除できます。一部はコミット済みで、コミットされていないページもあります。 つまり、各ページの現在のコミットメント状態を最初に決定することなく、ページの範囲をコミット解除できます。 ページのコミットを解除すると、メモリまたはディスク上のページング ファイル内の物理ストレージが解放されます。
ページがコミット解除されていても解放されていない場合、その状態は予約済みに変わります。 その後、 VirtualAllocEx を呼び出してコミットするか、 VirtualFreeEx を 呼び出して解放できます。 予約ページの読み取りまたは書き込みを試みると、アクセス違反の例外が発生します。
VirtualFreeEx 関数は、異なる状態 (予約済みページとコミット済みページ) にあるページの範囲を解放できます。 つまり、各ページの現在のコミットメント状態を最初に決定することなく、ページの範囲を解放できます。 VirtualAllocEx によって最初に予約されたページの範囲全体を同時に解放する必要があります。
ページが解放されると、その状態は free に変わり、後続の割り当て操作で使用できます。 メモリが解放またはコミット解除された後、メモリを再度参照することはできません。 そのメモリに含まれている可能性のある情報は、永遠に失われます。 フリー ページの読み取りまたは書き込みを試みると、アクセス違反の例外が発生します。 情報を保持する必要がある場合は、情報を含むメモリをデコミットしたり、メモリを解放したりしないでください。
VirtualFreeEx 関数は、メモリの AWE リージョンで使用でき、アドレス空間を解放するときに、リージョン内のすべての物理ページ マッピングを無効にします。 ただし、物理ページは削除されず、アプリケーションで使用できます。 アプリケーションは、物理ページを解放するために FreeUserPhysicalPages を明示的に呼び出す必要があります。 プロセスが終了すると、すべてのリソースが自動的にクリーンアップされます。
Windows 10バージョン 1709 以降およびWindows 11: エンクレーブの使用が完了したら、DeleteEnclave を呼び出します。 VirtualFree または VirtualFreeEx 関数を呼び出して VBS エンクレーブを削除することはできません。 引き続き VirtualFree または VirtualFreeEx を呼び出すことで、SGX エンクレーブ を削除できます。
Windows 10、バージョン 1507、Windows 10、バージョン 1511、Windows 10、バージョン 1607、Windows 10、バージョン 1703: エンクレーブの使用が完了したら削除するには、VirtualFree または VirtualFreeEx 関数を呼び出し、次の値を指定します。
- lpAddress パラメーターのエンクレーブのベース アドレス。
- dwSize パラメーターの場合は 0。
- dwFreeType パラメーターのMEM_RELEASE。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows XP [デスクトップ アプリ | UWP アプリ] |
サポートされている最小のサーバー | Windows Server 2003 [デスクトップ アプリのみ | UWP アプリ] |
対象プラットフォーム | Windows |
ヘッダー | memoryapi.h (Windows.h、Memoryapi.h を含む) |
Library | onecore.lib |
[DLL] | Kernel32.dll |