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 パラメーターから までの範囲内の 1 つ以上のバイトを含むすべてのメモリ ページをコミット解除します(lpAddress+dwSize)。 つまり、たとえば、ページ境界をまたぐ 2 バイトのメモリ領域により、両方のページがコミット解除されます。 lpAddressVirtualAlloc によって返されるベース アドレスで、dwSize が 0 (ゼロ) の場合、関数は VirtualAlloc によって割り当てられたリージョン全体をデコミットします。 その後、リージョン全体が予約状態になります。

[in] dwFreeType

空き操作の種類。 このパラメーターには次のいずれかの値を指定する必要があります。

意味
MEM_DECOMMIT
0x00004000
コミットされたページの指定された領域をデコミットします。 操作の後、ページは予約済みの状態になります。

コミットされていないページのコミットを解除しようとしても、関数は失敗しません。 つまり、現在のコミットメント状態を最初に決定することなく、ページの範囲をコミット解除できます。

lpAddress パラメーターがエンクレーブのベース アドレスを提供する場合、MEM_DECOMMIT値はサポートされません。 これは、動的メモリ管理 (つまり SGX1) をサポートしないエンクレーブに当てはまります。 SGX2 エンクレーブでは、エンクレーブ内の任意の場所に MEM_DECOMMIT できます。

MEM_RELEASE
0x00008000
ページの指定した領域またはプレースホルダーを解放します (プレースホルダーの場合、アドレス空間は解放され、他の割り当てで使用できます)。 この操作の後、ページは空き状態になります。

この値を指定する場合、 dwSize は 0 (ゼロ) である必要があり、 lpAddress はリージョンの予約時に VirtualAlloc 関数によって返されるベース アドレスを指す必要があります。 この条件が両方とも満たされないと、エラーが発生します。

リージョン内のページが現在コミットされている場合、関数は最初にコミットを解除してから解放します。

異なる状態のページ (予約済みページとコミット済みページ) を解放しようとしても、関数は失敗しません。 つまり、現在のコミットメント状態を最初に決定することなく、ページの範囲を解放できます。

MEM_RELEASEを使用する場合、このパラメーターは次のいずれかの値を追加で指定できます。

意味
MEM_COALESCE_PLACEHOLDERS
0x00000001
隣接する 2 つのプレースホルダーを結合するには、 を指定します MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS。 プレースホルダーを結合する場合、 lpAddressdwSize は、マージするプレースホルダーの全体的な範囲と完全に一致する必要があります。
MEM_PRESERVE_PLACEHOLDER
0x00000002
割り当てをプレースホルダーに解放します (プレースホルダーを VirtualAlloc2 または Virtual2AllocFromApp を使用してプライベート割り当てに置き換えた後)。

プレースホルダーを 2 つのプレースホルダーに分割するには、 を指定 MEM_RELEASE | MEM_PRESERVE_PLACEHOLDERします。

戻り値

関数が成功すると、戻り値は 0 以外になります。

関数が失敗した場合は、0 を返します。 詳細なエラー情報を得るには、GetLastError を呼び出します。

解説

プロセス仮想アドレス空間内のメモリの各ページには 、ページ状態があります。 VirtualFree 関数は、さまざまな状態にあるページの範囲をデコミットできます。一部はコミット済みで、コミットされていないページもあります。 つまり、各ページの現在のコミットメント状態を最初に決定することなく、ページの範囲をコミット解除できます。 ページのコミットを解除すると、メモリまたはディスク上のページング ファイル内の物理ストレージが解放されます。

ページがコミット解除されていても解放されていない場合、その状態は予約済みに変わります。 その後、 VirtualAlloc を呼び出してコミットするか、 VirtualFree を呼び出して解放できます。 予約ページの読み取りまたは書き込みを試みると、アクセス違反の例外が発生します。

VirtualFree 関数は、さまざまな状態 (予約済みページとコミット済みページ) の範囲を解放できます。 つまり、各ページの現在のコミットメント状態を最初に決定することなく、ページの範囲を解放できます。 VirtualAlloc 関数によって最初に予約されたページの範囲全体を同時に解放する必要があります。

ページが解放されると、その状態は free に変わり、後続の割り当て操作で使用できます。 メモリが解放またはコミット解除された後、メモリを再度参照することはできません。 そのメモリに含まれている可能性のある情報は、永遠に失われます。 空きページから読み取ったり、空きページに書き込んだりしようとすると、アクセス違反の例外が発生します。 情報を保持する必要がある場合は、情報を含むメモリをデコミットしたり、メモリを解放したりしないでください。

VirtualFree 関数は、メモリの 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

関連項目

メモリ管理関数

仮想メモリ関数

VirtualFreeEx

VBS エンクレーブで使用できる Vertdll API