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 パラメーターがエンクレーブのベース アドレスを提供する場合、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