> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XMemVirtualAlloc

> XMemVirtualAlloc

# XMemVirtualAlloc

呼び出し元プロセスの仮想アドレス空間内のページ領域を予約、コミット、または状態変更します。

<Note>
  標準の Win32 <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc" target="_blank">VirtualAlloc</a> とは異なり、この関数によって割り当てられるメモリは自動的にゼロ初期化されることが *保証されません*。
</Note>

## Syntax

```cpp theme={null}
PVOID XMemVirtualAlloc(  
         PVOID BaseAddress,  
         SIZE_T Size,  
         DWORD AllocationType,  
         ULONGLONG XMemFlags,  
         DWORD PageProtection  
)  
```

### Parameters

*BaseAddress*   \_In\_opt\_<br />型: PVOID

割り当てるリージョンの開始アドレス。メモリを予約する場合、指定されたアドレスは割り当て粒度 (XBOX では 4K、64K、または 2MB) の最も近い倍数に切り下げられます。メモリが既に予約されていてコミットされる場合、アドレスは次のページ境界に切り下げられます。このパラメーターが NULL の場合、システムがリージョンを割り当てる場所を決定します。

<br />

*Size*   \_In\_<br />型: SIZE\_T

リージョンのサイズ (バイト単位)。*BaseAddress* パラメーターが NULL の場合、この値は次のページ境界に切り上げられます。それ以外の場合、割り当てられるページには *BaseAddress* から *BaseAddress*+*Size* の範囲内の 1 バイト以上を含むすべてのページが含まれます。つまり、ページ境界にまたがる 2 バイトの範囲では、両方のページが割り当てられるリージョンに含まれます。

<br />

*AllocationType*   \_In\_<br />型: DWORD

メモリ割り当ての種類。このパラメーターには、次のいずれかの値を含める必要があります。

| 値 | 意味 | |
| - | - | - |
| **MEM\_COMMIT**<br />0x00001000 | 指定された予約済みメモリ ページに対して (メモリの全体サイズから) メモリ料金を割り当てます。1 ステップでページを予約およびコミットするには、\`MEM\_COMMIT | MEM\_RESERVE\` を指定して **XMemVirtualAlloc** を呼び出します。<br />**MEM\_RESERVE** なしで **MEM\_COMMIT** および NULL 以外の *BaseAddress* を指定して特定のアドレス範囲をコミットしようとすると、範囲全体が既に予約されていない限り失敗します。結果のエラー コードは **ERROR\_INVALID\_ADDRESS** です。<br />既にコミットされているページをコミットしようとしても、関数は失敗しません。つまり、各ページの現在のコミット状態を最初に判断せずにページをコミットできます。 |
| **MEM\_RESERVE**<br />0x00002000 | プロセスの仮想アドレス空間の範囲を、実際の物理ストレージをメモリに割り当てずに予約します。予約済みのページは、**XMemVirtualAlloc** 関数への後続の呼び出しでコミットするか、**XMemMapPhysicalPages** を使用して物理ページを直接マップできます。<br />**malloc** や **new** などのその他のメモリ割り当て関数は、予約済みのメモリ範囲が解放されるまでその範囲を使用できません。<br /><br />XBOX 上の *Microsoft Game Development Kit (GDK)* の新しいメモリ マネージャーでは、予約時にページ保護とキャッシュ整合性設定が必要となる点にご注意ください。これは XBOX OS の以前のバージョンからの変更点です。 | |
| **MEM\_RESERVE\_PLACEHOLDER**<br />0x00040000 | プレースホルダーは仮想アドレスを予約しますが、VA をページ サイズやページ保護にロックしません。ページ サイズおよびページ保護の選択は、**MEM\_REPLACE\_PLACEHOLDER** を使用してプレースホルダーを実際の予約またはコミットに置き換える際に選択されます。プレースホルダーを作成するには、**MEM\_RESERVE \| MEM\_RESERVE\_PLACEHOLDER** を指定し、PageProtection を **PAGE\_NOACCESS** に設定して **XMemVirtualAlloc** を呼び出します。**MEM\_RESERVE\_PLACEHOLDER** を使用すると、将来 **MEM\_2MB\_PAGES** で使用できることを保証するために、常に 2MB にアラインされたアドレスが返されます。ただし、予約後、プレースホルダーは **MEM\_RELEASE \| MEM\_PRESERVE\_PLACEHOLDER** を指定した VirtualFree を使用して任意の粒度 (4K、64K、または 2MB) で分割できます。 | |
| **MEM\_REPLACE\_PLACEHOLDER**<br />0x00004000 | プレースホルダーを通常のプライベート割り当てに置き換えます。プレースホルダーを置き換える際は、BaseAddress と Size がプレースホルダーのものと正確に一致する必要があります。プレースホルダーをプライベート割り当てに置き換えた後、その割り当てを解放してプレースホルダーに戻すには、**VirtualFree** および **VirtualFreeEx** の **dwFreeType** パラメーターを参照してください。 | |

このパラメーターは、次の値を指定することもできます。

| 値 | 意味 |
| - | - |
| **MEM\_2MB\_PAGES**<br />0x20000000 | 2MB のページ サイズを指定します。 |
| **MEM\_64K\_PAGES**<br />0x20400000 | 64K のページ サイズを指定します。 |

<Note>
  ERA タイトルでは、**MEM\_LARGE\_PAGES** は 64K ページを表し、Windows デスクトップでは 2MB ページを表していました。あいまいさのため、*Microsoft Game Development Kit (GDK)* からは削除されています。
</Note>

<br />

*XMemFlags*   \_In\_<br />型: ULONGLONG

XBOX で特定の特殊なメモリ タイプを取得するために使用されます。このパラメーターには、次のいずれかの値を含める必要があります。

| 値 | 意味 |
| - | - |
| **XMEM\_CPU**<br />0x00000001 | CPU のみからアクセス可能なメモリを割り当てます。 |
| **XMEM\_GRAPHICS**<br />0x00000003 | CPU と GPU の両方からアクセス可能なメモリを割り当てます。**XMEM\_GRAPHICS** でコミットされたメモリは、GPU のページ テーブルにマップされます。 |
| **XMEM\_GRAPHICS\_32BIT\_ADDRESS**<br />0x00000007 | 自動的に割り当てられるアドレスがアドレス空間の下位 4GB にあることを指定します。このフラグを使用してコミットされたメモリは、GPU からもアクセス可能です。 |

XBOX では、上位ビットが使用されないことを保証する制限された仮想メモリ アドレスでメモリを割り当てることができます。次の値のいずれかを使用すると、示された数のビットを使用するようにアドレスが制限されます。**XMEM\_40BIT\_ADDRESS** (0x00007000ULL)、**XMEM\_41BIT\_ADDRESS** (0x00006000ULL)、**XMEM\_42BIT\_ADDRESS** (0x00005000ULL)、**XMEM\_43BIT\_ADDRESS** (0x00004000ULL)、**XMEM\_44BIT\_ADDRESS** (0x00003000ULL)、**XMEM\_45BIT\_ADDRESS** (0x00002000ULL)、**XMEM\_46BIT\_ADDRESS** (0x00001000ULL)。

<Note>
  グラフィックス メモリは、D3D12Device が作成される前、または D3DConfigureVirtualMemory が呼び出される前には割り当てられません。GPU から見えるメモリを要求する場合、タイトルは明示的なグラフィックス ページ保護フラグも指定することが *必須* です。CPU ページ保護設定に基づく既定はもう存在しません。これは以前の XBOX OS バージョンからの変更点です。
</Note>

このパラメーターは、次の値を指定することもできます。

| 値 | 意味 |
| - | - |
| **XMEM\_TOOL**<br />0x00000010 | 割り当てをタイトル パーティションではなくツール パーティションに課金することを指定します。このフラグでは、*AllocationType* パラメーターに **MEM\_2MB\_PAGES** または **MEM\_64K\_PAGES** を指定する必要があります。 |
| **XMEM\_MAPPABLE**<br />0x00000020 | 割り当てが、[XMemMapPhysicalPages](/ja-jp/reference/system/xmem/functions/xmemmapphysicalpages) を通じて物理ページ マッピングに使用されるアドレス予約であることを指定します。このフラグでは、*AllocationType* パラメーターに **MEM\_RESERVE** および **MEM\_2MB\_PAGES** または **MEM\_64K\_PAGES** を指定する必要があります。 |

Advanced タイトル メモリ モードを使用している場合の Anaconda デバイスおよび Anaconda をエミュレートする Dante デバイスでは、次のパラメーターも適用できます。これらのパラメーターはその他のすべての場合には無視されます。

<Note>
  これらのフラグは任意です。指定されていない場合、すべてのグラフィックス割り当ては既定で XMEM\_GPU\_OPTIMAL\_BANDWIDTH\_PREFERRED を使用し、その他のすべての割り当ては既定で XMEM\_STANDARD\_BANDWIDTH\_PREFERRED を使用します。
</Note>

| 値 | 意味 |
| - | - |
| **XMEM\_STD\_BW\_REQ** または <br />**XMEM\_STANDARD\_BANDWIDTH\_REQUIRED**<br />0x00000080 | 割り当てを標準帯域幅メモリを使用して満たす必要があることを指定します。 |
| **XMEM\_STD\_BW\_PREF** または <br />**XMEM\_STANDARD\_BANDWIDTH\_PREFERRED**<br />0x00000180 | 割り当てが標準帯域幅メモリを優先し、標準帯域幅メモリが枯渇した場合にのみ GPU 最適帯域幅メモリを使用することを指定します。 |
| **XMEM\_GPU\_OPTBW\_REQ** または <br />**XMEM\_GPU\_OPTIMAL\_BANDWIDTH\_REQUIRED**<br />0x00000280 | 割り当てを GPU 最適帯域幅メモリを使用して満たす必要があることを指定します。 |
| **XMEM\_GPU\_OPTBW\_PREF** または <br />**XMEM\_GPU\_OPTIMAL\_BANDWIDTH\_PREFERRED**<br />0x00000380 | 割り当てが GPU 最適帯域幅メモリを優先し、GPU 最適帯域幅メモリが枯渇した場合にのみ標準帯域幅メモリを使用することを指定します。 |

*XMemFlags* パラメーターには、オプションの 4 文字コード タグが含まれます。文字は a-z、A-Z、0-9、および \$ のいずれかを使用できます。この関数 [XMemMakeTag](/ja-jp/reference/system/xmem/functions/xmemmaketag) を使用して、タグ値の適切なエンコードを正しいビット位置で構築できます。タグはコミットされたメモリ リージョンにのみ関連付けることができ、予約には関連付けられません。この 4 文字コード タグはパラメーターの上位 24 ビットで表されます。タグは [XMemVirtualQuery](/ja-jp/reference/system/xmem/functions/xmemvirtualquery) を通じて取得でき、PIX メモリ分析でも表示されます。

例:

```cpp theme={null}
PVOID mem = XMemVirtualAlloc(NULL, size, MEM_64K_PAGES | MEM_COMMIT, XMemMakeTag('Fred') | XMEM_CPU, PAGE_READWRITE);
```

<br />

*PageProtection*   \_In\_<br />型: DWORD

割り当てるページ リージョンのメモリ保護。ページをコミットする場合、<a href="https://learn.microsoft.com/en-us/windows/desktop/Memory/memory-protection-constants">メモリ保護定数</a> のいずれかを指定できます。

**XMEM\_GRAPHICS** または **XMEM\_GRAPHICS\_32BIT\_ADDRESS** を指定する場合、*PageProtection* パラメーターに次の XBOX 固有の値のいずれかが許可され、1 つが必須です。この要件は以前の XBOX OS バージョンからの変更点です。これらの値は、**XMEM\_GRAPHICS** で割り当てられた範囲内のメモリ アドレスに対して他のメモリ管理関数 (例: <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualprotect">VirtualProtect</a>) にも指定できます。

| 値 | 意味 |
| - | - |
| **PAGE\_GRAPHICS\_NOACCESS**<br />0x0800 | メモリが GPU からアクセス不可能であることを指定します。 |
| **PAGE\_GRAPHICS\_READONLY**<br />0x1000 | メモリが GPU 上で読み取り専用であることを指定します。 |
| **PAGE\_GRAPHICS\_READWRITE**<br />0x2000 | メモリが GPU 上で読み書き可能であることを指定します。 |
| **PAGE\_GRAPHICS\_EXECUTE**<br />0x4000<br /><br />**GRAPHICS\_EXECUTE\_READ**<br />0x8000<br /><br />**PAGE\_GRAPHICS\_EXECUTE\_READWRITE**<br />0x10000 | メモリが GPU 上で実行可能であることを指定します。コマンド バッファーにはこれが必要です。 |

このパラメーターは、次の値を指定することもできます。

| 値 | 意味 |
| - | - |
| **PAGE\_GRAPHICS\_COHERENT**<br />0x20000 | GPU と共有されるメモリが、CPU と GPU のキャッシュ間で整合性を保つことを指定します。 |
| **PAGE\_GRAPHICS\_NOCACHE**<br />0x40000 | GPU によるアクセス時にメモリをキャッシュしないことを指定します。このフラグは XBOX Series X\|S 本体でのみ適用されます。 |

### Return value

型: PVOID

関数が成功した場合、戻り値は割り当てられたページ リージョンのベース アドレスです。

関数が失敗した場合、戻り値は **NULL** です。拡張エラー情報を取得するには、<a href="https://msdn.microsoft.com/library/windows/desktop/ms679360(v=vs.85).aspx">GetLastError</a> を呼び出します。

## Remarks

各ページには関連付けられた <a href="https://learn.microsoft.com/en-us/windows/desktop/Memory/page-state">ページ状態</a> があります。**XMemVirtualAlloc** 関数は次の操作を実行できます:

* 予約済みページ領域のコミット
* 空きページ領域の予約
* 空きページ領域の予約とコミットを同時に実行

**XMemVirtualAlloc** は予約済みページを予約することはできません。既にコミットされているページをコミットすることはできます。つまり、ページが既にコミットされているかどうかに関係なく一定範囲のページをコミットでき、関数は失敗しません。

**XMemVirtualAlloc** を使用してページのブロックを予約し、その後追加の **XMemVirtualAlloc** の呼び出しにより予約済みブロックから個別のページをコミットできます。これにより、プロセスは必要になるまで物理ストレージを消費せずに仮想アドレス空間の範囲を予約できます。

*BaseAddress* パラメーターが **NULL** でない場合、関数は *BaseAddress* と *Size* パラメーターを使用して割り当てるページ リージョンを計算します。ページ範囲全体の現在の状態は、*AllocationType* パラメーターで指定された割り当て種別と互換性がある必要があります。そうでない場合、関数は失敗し、ページはまったく割り当てられません。この互換性要件は、前述したように、既にコミットされたページのコミットを妨げるものではありません。

**XMemVirtualAlloc** 関数を使用して、物理ページのマッピング用に指定された呼び出し元プロセスの仮想アドレス空間内のメモリ リージョンを予約できます。このメモリ リージョンは、アプリケーションが必要に応じて物理ページを仮想メモリにマップしたり解除したりするために使用できます。*AllocationType* パラメーターには **MEM\_RESERVE** および **MEM\_64K\_PAGES** の値を設定する必要があります。**MEM\_COMMIT** の値は設定しないでください。*XMemFlags* パラメーターには **XMEM\_MAPPABLE** を設定する必要があります。この方法で予約されたアドレス空間は、[XMemMapPhysicalPages](/ja-jp/reference/system/xmem/functions/xmemmapphysicalpages) API を使用してコミットされます。

<a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualfree">VirtualFree</a> 関数は、コミット済みのページをデコミットしてページのストレージを解放したり、コミット済みのページを同時にデコミットして解放したりできます。また、予約済みのページを解放して空きページにすることもできます。

XBOX 固有のメモリ特性の拡張機能を提供することに加えて、この API は、返されるメモリがゼロ初期化されていることを保証する契約を強制しないという点で <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc">VirtualAlloc</a> と異なります。また、**XMemVirtualAlloc** は以前のメモリ内容を保持することを保証しません。ゲームにおける **XMemVirtualAlloc** のほとんどの使用例では、グラフィックス メモリを取得すること (これは通常、ゼロ初期化の恩恵を受けません) や、ゼロ初期化からほとんど有用な値を得られないヒープ実装にメモリを追加することが関係しています。さらに、呼び出し元が任意のタイミングで返されたメモリのゼロ初期化を実装することは自明です。<a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc">VirtualAlloc</a> のこの保証を強制しないことで、**XMemVirtualAlloc** の実装により高いパフォーマンスを提供できる柔軟性が生まれます。

**XMemVirtualAlloc** は、この API 呼び出しを通じて取得されるメモリがすぐに利用可能であるという点でも <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc">VirtualAlloc</a> と異なります。対照的に、<a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc">VirtualAlloc</a> によって返されるメモリ アドレスは、最初のアクセス時にコストの高いページ フォールト操作を通じてのみ物理ページが割り当てられます。

**XMemVirtualAlloc** で割り当てられたメモリは、<a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualfree">VirtualFree</a> で解放されるものと想定されます。

**PAGE\_NOCACHE** および **PAGE\_WRITECOMBINE** ページ保護フラグは、メモリの予約時に固定され、後のコミット要求では変更できません。メモリのコミット時にこれらのフラグの状態を変更しようとしても、警告なく無視されます。メモリ コミットは成功しますが、メモリはこれらのフラグの元の状態を保持します。

例:

```cpp theme={null}
// Allocate standard CPU only memory, using default (4K) pages
PVOID cpuMemory = XMemVirtualAlloc (NULL,
                                    1024 * 1024,
                                    MEM_RESERVE | MEM_COMMIT,
                                    XMEM_CPU,
                                    PAGE_READWRITE);
```

```cpp theme={null}
// Allocate 1MB of tooling memory using 64K pages
PVOID cpu64kmemory = XMemVirtualAlloc (NULL,
                                       1024 * 1024,
                                       MEM_64K_PAGES | MEM_RESERVE | MEM_COMMIT,
                                       XMEM_TOOL | XMEM_CPU,
                                       PAGE_READWRITE);
```

```cpp theme={null}
// Allocate 2MB graphics memory
PVOID gfx64kmemory = XMemVirtualAlloc (NULL,
                                       2 * 1024 * 1024,
                                       MEM_2MB_PAGES | MEM_RESERVE | MEM_COMMIT,
                                       XMEM_GRAPHICS,
                                       PAGE_READWRITE | PAGE_GRAPHICS_READONLY);
```

```cpp theme={null}
// Allocate 1MB of graphics memory using 64K pages in 32b address space
PVOID gfxmemory32b = XMemVirtualAlloc (NULL,
                                       1024 * 1024,
                                       MEM_64K_PAGES | MEM_RESERVE | MEM_COMMIT,
                                       XMEM_GRAPHICS_32BIT_ADDRESS,
                                       PAGE_READONLY | PAGE_GRAPHICS_READWRITE);
```

```cpp theme={null}
// Reserve 1GB of CPU visible VA space using 64K pages
PVOID cpuReserve = XMemVirtualAlloc (NULL,
                                     1024 * 1024 * 1024,
                                     MEM_64K_PAGES | MEM_RESERVE,
                                     XMEM_CPU,
                                     PAGE_READWRITE);

// Now commit the first 2MB of the reservation
PVOID cpuCommit = XMemVirtualAlloc (cpuReserve,
                                    2 * 1024 * 1024,
                                    MEM_COMMIT,
                                    XMEM_CPU,
                                    PAGE_READWRITE);
```

```cpp theme={null}
// Reserve 4MB of visible VA space intended for direct physical page mapping
// Note that physical pages are always 64KB and this reservation assumes
// any allocations will be in 32 or 64 page (2MB\4MB) blocks
PVOID physicalReserve = XMemVirtualAlloc (NULL,
                                          4 * 1024 * 1024,
                                          MEM_2MB_PAGES | MEM_RESERVE,
                                          XMEM_GRAPHICS | XMEM_MAPPABLE,
                                          PAGE_READONLY | PAGE_GRAPHICS_COHERENT | PAGE_GRAPHICS_READWRITE);
```

## Requirements

**ヘッダー:** xmem.h

**ライブラリ:** xmem.lib

**サポートされているプラットフォーム:** XBOX One ファミリー本体および XBOX Series 本体

## See also

[XMem reference](/ja-jp/reference/system/xmem/xmem_members)<br />[XMemMapPhysicalPages](/ja-jp/reference/system/xmem/functions/xmemmapphysicalpages)<br /><a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualfree">VirtualFree</a>


## Related topics

- [Microsoft GDK ゲーム OS メモリ マネージャーの使用](/ja-jp/build/console-features/memory/system-memory-working.md)
- [XMemMapPhysicalPages](/ja-jp/reference/system/xmem/functions/xmemmapphysicalpages.md)
- [XMemMapPhysicalPagesScatter](/ja-jp/reference/system/xmem/functions/xmemmapphysicalpagesscatter.md)
- [XMemVirtualQuery](/ja-jp/reference/system/xmem/functions/xmemvirtualquery.md)
- [XMEM_OPTIONS](/ja-jp/reference/system/xmem/enums/xmem_options.md)
