VirtualAllocFromApp 函式 (memoryapi.h)

在呼叫程式的虛擬位址空間中保留、認可或變更頁面區域的狀態。 此函式配置的記憶體會自動初始化為零。

語法

PVOID VirtualAllocFromApp(
  [in, optional] PVOID  BaseAddress,
  [in]           SIZE_T Size,
  [in]           ULONG  AllocationType,
  [in]           ULONG  Protection
);

參數

[in, optional] BaseAddress

要配置之區域的起始位址。 如果保留記憶體,則指定的位址會四捨五入到最接近的配置粒度倍數。 如果記憶體已保留且正在認可,位址會四捨五入至下一個頁面界限。 若要判斷頁面的大小和主計算機上的配置粒度,請使用 getSystemInfo 函式 。 如果此參數 NULL,則系統會決定要配置區域的位置。

[in] Size

區域的大小,以位元組為單位。 如果 BaseAddress 參數 NULL,這個值會四捨五入至下一個頁面界限。 否則,配置的頁面會包含範圍中包含一或多個字節的所有頁面,範圍從 BaseAddressBaseAddress+Size。 這表示跨越頁面界限的 2 位元組範圍會導致這兩個頁面包含在配置的區域。

[in] AllocationType

記憶體配置的類型。 此參數必須包含下列其中一個值。

價值 意義
MEM_COMMIT
0x00001000
為指定的保留記憶體分頁配置記憶體費用(從記憶體的整體大小和磁碟上的分頁檔案。 函式也保證當呼叫端稍後最初存取記憶體時,內容會是零。 除非實際存取虛擬位址,否則不會配置實際的實體頁面。

若要在一個步驟中保留和認可頁面,請使用 MEM_COMMIT | MEM_RESERVE呼叫 virtualAllocFromApp

除非已保留整個範圍,否則嘗試藉由指定不含 MEM_RESERVEMEM_COMMIT,以及非NULLBaseAddress 失敗,以認可特定位址範圍。 產生的錯誤碼 ERROR_INVALID_ADDRESS

嘗試認可已經認可的頁面,並不會讓函式失敗。 這表示您可以認可頁面,而不需要先判斷每個頁面的目前承諾狀態。

MEM_RESERVE
0x00002000
保留進程虛擬位址空間的範圍,而不需在記憶體或磁碟上的分頁檔案中配置任何實際的實體記憶體。

您可以在後續呼叫 virtualAllocFromApp 函式時認可保留頁面。 若要在一個步驟中保留和認可頁面,請使用 MEM_COMMIT | MEM_RESERVE呼叫 virtualAllocFromApp

其他記憶體配置函式,例如 mallocLocalAlloc,在釋放記憶體之前,無法使用保留的記憶體範圍。

MEM_RESET
0x00080000
表示 BaseAddressSize 所指定的記憶體範圍中的數據已不再感興趣。 頁面不應該讀取或寫入至分頁檔案。 不過,稍後會再次使用記憶體區塊,因此不應予以認可。 這個值不能與任何其他值搭配使用。

使用此值不保證使用 MEM_RESET 運作的範圍將包含零。 如果您想要範圍包含零,請取消認可記憶體,然後重新認可它。

當您指定 MEM_RESET時,VirtualAllocFromApp 函式會忽略 Protection的值。 不過,您必須將 Protection 設定為有效的保護值,例如 PAGE_NOACCESS

VirtualAllocFromApp 如果您使用 MEM_RESET,且記憶體範圍會對應至檔案,則傳回錯誤。 只有在共享檢視對應至分頁檔案時才可接受。

MEM_RESET_UNDO
0x1000000
MEM_RESET_UNDO 應該只在先前成功套用 MEM_RESET 的位址範圍上呼叫。 它表示 BaseAddress所指定記憶體範圍中的數據Size 對呼叫者感興趣,並嘗試反轉 MEM_RESET的效果。 如果函式成功,這表示指定位址範圍中的所有數據都保持不變。 如果函式失敗,則位址範圍中至少有一些數據已取代為零。

這個值不能與任何其他值搭配使用。 如果在先前未 MEM_RESET 的位址範圍上呼叫 MEM_RESET_UNDO,則行為未定義。 當您指定 MEM_RESET時,VirtualAllocFromApp 函式會忽略 Protection的值。 不過,您必須將 Protection 設定為有效的保護值,例如 PAGE_NOACCESS

 

此參數也可以指定下列值,如所示。

價值 意義
MEM_LARGE_PAGES
0x20000000
使用大型頁面支援 設定記憶體,

大小和對齊必須是大頁面最小值的倍數。 若要取得此值,請使用 getLargePageMinimum 函式

如果您指定這個值,您也必須指定 MEM_RESERVEMEM_COMMIT

MEM_PHYSICAL
0x00400000
保留位址範圍,可用來對應 位址視窗化延伸模組 (AWE) 頁面。

這個值必須與 MEM_RESERVE 搭配使用,而且沒有其他值。

MEM_TOP_DOWN
0x00100000
配置最高可能位址的記憶體。 這比一般配置慢,尤其是在有許多配置時。
MEM_WRITE_WATCH
0x00200000
讓系統追蹤在配置區域中寫入的頁面。 如果您指定此值,也必須指定 MEM_RESERVE

若要擷取自配置區域或重設寫入追蹤狀態以來已寫入的頁面位址,請呼叫 getWriteWatch 函式 。 若要重設寫入追蹤狀態,請呼叫 GetWriteWatchResetWriteWatch。 在釋放區域之前,記憶體區域仍會啟用寫入追蹤功能。

[in] Protection

要配置之頁面區域的記憶體保護。 如果正在認可頁面,您可以指定其中一個 記憶體保護常數。 下列常數會產生錯誤:

  • PAGE_EXECUTE
  • PAGE_EXECUTE_READ
  • PAGE_EXECUTE_READWRITE
  • PAGE_EXECUTE_WRITECOPY

傳回值

如果函式成功,傳回值就是頁面所配置區域的基位址。

如果函式失敗,則傳回值 NULL。 若要取得擴充的錯誤資訊,請呼叫 GetLastError

言論

您可以從具有 Just-In-Time (JIT) 功能的 Windows 市集應用程式呼叫 VirtualAllocFromApp,以使用 JIT 功能。 應用程式必須在應用程式指令清單檔案中包含 codeGeneration 功能,才能使用 JIT 功能。

每個頁面都有相關聯的 頁面狀態VirtualAllocFromApp 函式可以執行下列作業:

  • 認可保留頁面的區域
  • 保留免費頁面的區域
  • 同時保留並認可免費頁面的區域
VirtualAllocFromApp 無法保留保留的頁面。 它可以認可已經認可的頁面。 這表示不論頁面是否已認可,都可以認可一系列頁面,而且函式不會失敗。

您可以使用 VirtualAllocFromApp 來保留頁面區塊,然後對 virtualAllocFromApp 進行其他 呼叫,以認可來自保留區塊的個別頁面。 這可讓進程保留其虛擬位址空間的範圍,而不需要取用實體記憶體,直到需要為止。

如果 BaseAddress 參數不是 NULL,則函式會使用 BaseAddress,並 Size 參數來計算要配置的頁面區域。 整個頁面範圍的目前狀態必須與 AllocationType 參數所指定的配置類型相容。 否則,函式會失敗,且未配置任何頁面。 此相容性需求不會排除認可已認可的頁面,如先前所述。

VirtualAllocFromApp 不允許建立可執行的頁面。

VirtualAllocFromApp 函式可用來在指定行程的虛擬位址空間內保留記憶體 (AWE) 記憶體 視窗化延伸模組區域。 然後,您可以使用此記憶體區域,將實體頁面對應到應用程式所需的虛擬記憶體和移出。 AllocationType 參數中必須設定 MEM_PHYSICALMEM_RESERVE 值。 不得設定 MEM_COMMIT 值。 頁面保護必須設定為 PAGE_READWRITE

VirtualFree 函式可以取消認可頁面、釋放頁面的記憶體,或同時解除認可和釋放認可的頁面。 它也可以釋放保留頁面,使其成為免費頁面。

建立將可執行的區域時,呼叫程式會負責確保透過適當的呼叫 FlushInstructionCache 快取一致性,一旦設定程式代碼就位。 否則,嘗試從新可執行區域執行程序代碼可能會產生無法預期的結果。

要求

要求 價值
最低支援的用戶端 Windows 10 [傳統型應用程式 |UWP 應用程式]
支援的最低伺服器 Windows Server 2016 [傳統型應用程式 |UWP 應用程式]
目標平臺 窗戶
標頭 memoryapi.h (包括 Windows.h)
連結庫 WindowsApp.lib
DLL Kernel32.dll

另請參閱

記憶體管理功能

虛擬記憶體函式

VirtualAlloc

VirtualAllocEx

VirtualFree

VirtualLock

VirtualProtectFromApp

VirtualQuery