> ## 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

Reserva, confirma o cambia el estado de una región de páginas en el espacio de direcciones virtuales del proceso que realiza la llamada.

<Note>
  A diferencia de la función estándar de Win32 <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc" target="_blank">VirtualAlloc</a>, *no* se garantiza que la memoria asignada por esta función se inicialice automáticamente a cero.
</Note>

## Sintaxis

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

### Parámetros

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

Dirección inicial de la región que se va a asignar. Si la memoria se está reservando, la dirección especificada se redondea hacia abajo hasta el múltiplo más cercano de la granularidad de asignación (4K, 64K o 2 MB en XBOX). Si la memoria ya está reservada y se está confirmando, la dirección se redondea hacia abajo hasta el siguiente límite de página. Si este parámetro es NULL, el sistema determina dónde asignar la región.

<br />

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

Tamaño de la región, en bytes. Si el parámetro *BaseAddress* es NULL, este valor se redondea hacia arriba hasta el siguiente límite de página. De lo contrario, las páginas asignadas incluyen todas las páginas que contienen uno o más bytes en el intervalo desde *BaseAddress* hasta *BaseAddress*+*Size*. Esto significa que un intervalo de 2 bytes que abarque un límite de página hace que ambas páginas se incluyan en la región asignada.

<br />

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

Tipo de asignación de memoria. Este parámetro debe contener uno de los valores siguientes.

| Valor | Significado | |
| - | - | - |
| **MEM\_COMMIT**<br />0x00001000 | Asigna cargos de memoria (del tamaño total de la memoria) para las páginas de memoria reservadas especificadas. Para reservar y confirmar páginas en un solo paso, llame a **XMemVirtualAlloc** con \`MEM\_COMMIT | MEM\_RESERVE\`.<br />Intentar confirmar un intervalo de direcciones específico especificando **MEM\_COMMIT** sin **MEM\_RESERVE** y una dirección *BaseAddress* distinta de NULL produce un error, a menos que todo el intervalo ya se haya reservado. El código de error resultante es **ERROR\_INVALID\_ADDRESS**.<br />Un intento de confirmar una página que ya está confirmada no hace que la función produzca un error. Esto significa que puede confirmar páginas sin determinar primero el estado de confirmación actual de cada página. |
| **MEM\_RESERVE**<br />0x00002000 | Reserva un intervalo del espacio de direcciones virtuales del proceso sin asignar ningún almacenamiento físico real en la memoria. Puede confirmar las páginas reservadas en llamadas posteriores a la función **XMemVirtualAlloc**, o asignar páginas físicas directamente mediante **XMemMapPhysicalPages**.<br />Otras funciones de asignación de memoria, como **malloc** y **new**, no pueden usar un intervalo de memoria reservado hasta que se libere. <br /><br />Tenga en cuenta que el nuevo administrador de memoria del *Microsoft Game Development Kit (GDK)* en XBOX requiere la configuración de protección de página y coherencia de caché en el momento de la reserva; esto es un cambio con respecto a la versión anterior del sistema operativo de XBOX. | |
| **MEM\_RESERVE\_PLACEHOLDER**<br />0x00040000 | Un marcador de posición reserva direcciones virtuales, pero no bloquea la VA a un tamaño de página ni a una protección de página. La elección del tamaño de página y la protección de página se realiza al reemplazar el marcador de posición por una reserva o confirmación real mediante **MEM\_REPLACE\_PLACEHOLDER**. Para crear un marcador de posición, llame a **XMemVirtualAlloc** con **MEM\_RESERVE \| MEM\_RESERVE\_PLACEHOLDER** y PageProtection establecido en **PAGE\_NOACCESS**. El uso de **MEM\_RESERVE\_PLACEHOLDER** siempre devolverá una dirección alineada a 2 MB para garantizar que se pueda usar con **MEM\_2MB\_PAGES** en el futuro.  Sin embargo, una vez reservado, el marcador de posición puede dividirse con cualquier granularidad (4K, 64K o 2 MB) mediante VirtualFree con **MEM\_RELEASE \| MEM\_PRESERVE\_PLACEHOLDER**. | |
| **MEM\_REPLACE\_PLACEHOLDER**<br />0x00004000 | Reemplaza un marcador de posición por una asignación privada normal. Al reemplazar un marcador de posición, BaseAddress y Size deben coincidir exactamente con los del marcador de posición. Después de reemplazar un marcador de posición por una asignación privada, para volver a liberar esa asignación como marcador de posición, consulte el parámetro **dwFreeType** de **VirtualFree** y **VirtualFreeEx**. | |

Este parámetro también puede especificar los valores siguientes, según se indica.

| Valor | Significado |
| - | - |
| **MEM\_2MB\_PAGES**<br />0x20000000 | Especifica un tamaño de página de 2 MB. |
| **MEM\_64K\_PAGES**<br />0x20400000 | Especifica un tamaño de página de 64K. |

<Note>
  Para los títulos de ERA, **MEM\_LARGE\_PAGES** representaba páginas de 64K, y en Windows de escritorio representa páginas de 2 MB. Debido a esta ambigüedad, se ha quitado del *Microsoft Game Development Kit (GDK)*.
</Note>

<br />

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

Se usa en XBOX para obtener determinados tipos de memoria especializados. Este parámetro debe contener uno de los valores siguientes.

| Valor | Significado |
| - | - |
| **XMEM\_CPU**<br />0x00000001 | Asigna memoria a la que solo puede acceder la CPU. |
| **XMEM\_GRAPHICS**<br />0x00000003 | Asigna memoria a la que pueden acceder tanto la CPU como la GPU. Cualquier memoria confirmada con **XMEM\_GRAPHICS** se asignará a las tablas de páginas de la GPU. |
| **XMEM\_GRAPHICS\_32BIT\_ADDRESS**<br />0x00000007 | Especifica que la dirección asignada automáticamente está en los 4 GB inferiores del espacio de direcciones. La GPU también puede acceder a la memoria confirmada con esta marca. |

En XBOX es posible asignar memoria con una dirección de memoria virtual restringida que garantiza que no se usen los bits altos. Usar cualquiera de los valores siguientes restringirá la dirección para que use el número de bits indicado. **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>
  La memoria gráfica no se puede asignar antes de que se haya creado el D3D12Device o de que se haya llamado a D3DConfigureVirtualMemory. Si se solicita memoria que será visible para la GPU, los títulos están *obligados* a especificar también marcas de protección de página gráfica explícitas; ya no hay un valor predeterminado basado en la configuración de protección de página de la CPU. Esto es un cambio con respecto a las versiones anteriores del sistema operativo de XBOX.
</Note>

Este parámetro también puede especificar los valores siguientes, según se indica.

| Valor | Significado |
| - | - |
| **XMEM\_TOOL**<br />0x00000010 | Especifica que las asignaciones se cargan a la partición de herramientas en lugar de a la partición de título. Esta marca requiere que se especifique **MEM\_2MB\_PAGES** o **MEM\_64K\_PAGES** en el parámetro *AllocationType*. |
| **XMEM\_MAPPABLE**<br />0x00000020 | Especifica que la asignación es una reserva de direcciones que se usará para asignaciones de páginas físicas a través de [XMemMapPhysicalPages](/es/reference/system/xmem/functions/xmemmapphysicalpages). Esta marca requiere que se especifique **MEM\_RESERVE** y **MEM\_2MB\_PAGES** o **MEM\_64K\_PAGES** en el parámetro *AllocationType*. |

En los dispositivos Anaconda y los dispositivos Dante que emulan Anaconda, mientras se usa el modo de memoria de título Advanced, también se pueden aplicar los parámetros siguientes.  Estos parámetros se ignoran en todos los demás casos.

<Note>
  Estas marcas son opcionales.  Si no se especifican, todas las asignaciones gráficas usarán de forma predeterminada XMEM\_GPU\_OPTIMAL\_BANDWIDTH\_PREFERRED y todas las demás asignaciones usarán de forma predeterminada XMEM\_STANDARD\_BANDWIDTH\_PREFERRED.
</Note>

| Valor | Significado |
| - | - |
| **XMEM\_STD\_BW\_REQ** o <br />**XMEM\_STANDARD\_BANDWIDTH\_REQUIRED**<br />0x00000080 | Especifica que las asignaciones deben satisfacerse con memoria de ancho de banda estándar. |
| **XMEM\_STD\_BW\_PREF** o <br />**XMEM\_STANDARD\_BANDWIDTH\_PREFERRED**<br />0x00000180 | Especifica que las asignaciones deben preferir la memoria de ancho de banda estándar y usar memoria de ancho de banda óptimo para la GPU solo si la memoria de ancho de banda estándar se agota. |
| **XMEM\_GPU\_OPTBW\_REQ** o <br />**XMEM\_GPU\_OPTIMAL\_BANDWIDTH\_REQUIRED**<br />0x00000280 | Especifica que las asignaciones deben satisfacerse con memoria de ancho de banda óptimo para la GPU. |
| **XMEM\_GPU\_OPTBW\_PREF** o <br />**XMEM\_GPU\_OPTIMAL\_BANDWIDTH\_PREFERRED**<br />0x00000380 | Especifica que las asignaciones deben preferir la memoria de ancho de banda óptimo para la GPU y usar memoria de ancho de banda estándar solo si la memoria de ancho de banda óptimo para la GPU se agota. |

El parámetro *XMemFlags* incluye una etiqueta opcional de código de cuatro caracteres. Los caracteres pueden ser cualquiera de a-z, A-Z, 0-9 y \$. La función [XMemMakeTag](/es/reference/system/xmem/functions/xmemmaketag) se puede usar para construir la codificación correcta del valor de la etiqueta en la posición de bit correcta.  La etiqueta solo se puede asociar a regiones de memoria confirmadas, no a reservas. Esta etiqueta de código de cuatro caracteres estará representada por los 24 bits superiores del parámetro.  La etiqueta se puede recuperar a través de [XMemVirtualQuery](/es/reference/system/xmem/functions/xmemvirtualquery) y también se mostrará en el análisis de memoria de PIX.

Ejemplo:

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

<br />

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

Protección de memoria para la región de páginas que se va a asignar. Si las páginas se están confirmando, puede especificar cualquiera de las <a href="https://learn.microsoft.com/en-us/windows/desktop/Memory/memory-protection-constants">constantes de protección de memoria</a>.

Los siguientes valores específicos de XBOX se permiten para el parámetro *PageProtection*, y uno de ellos es obligatorio cuando se especifica **XMEM\_GRAPHICS** o **XMEM\_GRAPHICS\_32BIT\_ADDRESS**. Este requisito es un cambio con respecto a la versión anterior del sistema operativo de XBOX. Estos valores también se pueden especificar en otras funciones de administración de memoria (por ejemplo, <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualprotect">VirtualProtect</a>) para direcciones de memoria dentro de intervalos que se asignaron con **XMEM\_GRAPHICS**.

| Valor | Significado |
| - | - |
| **PAGE\_GRAPHICS\_NOACCESS**<br />0x0800 | Especifica que la memoria no será accesible en la GPU. |
| **PAGE\_GRAPHICS\_READONLY**<br />0x1000 | Especifica que la memoria será de solo lectura en la GPU. |
| **PAGE\_GRAPHICS\_READWRITE**<br />0x2000 | Especifica que la memoria será de lectura y escritura en la GPU. |
| **PAGE\_GRAPHICS\_EXECUTE**<br />0x4000<br /><br />**GRAPHICS\_EXECUTE\_READ**<br />0x8000<br /><br />**PAGE\_GRAPHICS\_EXECUTE\_READWRITE**<br />0x10000 | Especifica que la memoria será ejecutable en la GPU. Esto es necesario para los búferes de comandos. |

Este parámetro también puede especificar el valor siguiente, según se indica.

| Valor | Significado |
| - | - |
| **PAGE\_GRAPHICS\_COHERENT**<br />0x20000 | Especifica que la memoria compartida con la GPU se mantendrá coherente entre las cachés de la CPU y la GPU. |
| **PAGE\_GRAPHICS\_NOCACHE**<br />0x40000 | Especifica que la memoria no se almacena en caché cuando la GPU accede a ella. Esta marca solo es aplicable en las consolas XBOX Series X\|S. |

### Valor devuelto

Tipo: PVOID

Si la función se ejecuta correctamente, el valor devuelto es la dirección base de la región de páginas asignada.

Si la función no se ejecuta correctamente, el valor devuelto es **NULL**. Para obtener información de error extendida, llame a <a href="https://msdn.microsoft.com/library/windows/desktop/ms679360(v=vs.85).aspx">GetLastError</a>.

## Comentarios

Cada página tiene asociado un <a href="https://learn.microsoft.com/en-us/windows/desktop/Memory/page-state">estado de página</a>. La función **XMemVirtualAlloc** puede realizar las operaciones siguientes:

* Confirmar una región de páginas reservadas
* Reservar una región de páginas libres
* Reservar y confirmar simultáneamente una región de páginas libres

**XMemVirtualAlloc** no puede reservar una página reservada. Puede confirmar una página que ya está confirmada. Esto significa que puede confirmar un intervalo de páginas, independientemente de si ya se han confirmado, y la función no producirá un error.

Puede usar **XMemVirtualAlloc** para reservar un bloque de páginas y, a continuación, realizar llamadas adicionales a **XMemVirtualAlloc** para confirmar páginas individuales del bloque reservado. Esto permite a un proceso reservar un intervalo de su espacio de direcciones virtuales sin consumir almacenamiento físico hasta que sea necesario.

Si el parámetro *BaseAddress* no es **NULL**, la función usa los parámetros *BaseAddress* y *Size* para calcular la región de páginas que se va a asignar. El estado actual de todo el intervalo de páginas debe ser compatible con el tipo de asignación especificado por el parámetro *AllocationType*. De lo contrario, la función produce un error y no se asigna ninguna página. Este requisito de compatibilidad no impide confirmar una página ya confirmada, como se ha mencionado anteriormente.

La función **XMemVirtualAlloc** se puede usar para reservar una región de memoria dentro del espacio de direcciones virtuales del proceso que realiza la llamada designada para la asignación de páginas físicas. Esta región de memoria se puede usar después para asignar páginas físicas a la memoria virtual y desasignarlas de ella según lo requiera la aplicación. Los valores **MEM\_RESERVE** y **MEM\_64K\_PAGES** deben establecerse en el parámetro *AllocationType*; el valor **MEM\_COMMIT** no debe establecerse. **XMEM\_MAPPABLE** debe establecerse en el parámetro *XMemFlags*. El espacio de direcciones reservado de esta manera se confirma mediante la API [XMemMapPhysicalPages](/es/reference/system/xmem/functions/xmemmapphysicalpages).

La función <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualfree">VirtualFree</a> puede anular la confirmación de una página confirmada, liberando su almacenamiento, o puede anular la confirmación y liberar simultáneamente una página confirmada. También puede liberar una página reservada, convirtiéndola en una página libre.

Además de proporcionar extensiones para las características de memoria específicas de XBOX, esta API difiere de <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc">VirtualAlloc</a> en que no aplica un contrato que garantice que la memoria devuelta se inicialice a cero. **XMemVirtualAlloc** tampoco garantiza que se conserve el contenido anterior de la memoria. La mayoría de los casos de uso de **XMemVirtualAlloc** en los juegos implican obtener memoria gráfica (que normalmente no se beneficia de la inicialización a cero) o agregar memoria a implementaciones de montones que obtienen poco valor útil de la inicialización a cero. Además, es trivial para un autor de llamada implementar la inicialización a cero de la memoria devuelta en el momento que elija. Al no aplicar esta garantía de <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc">VirtualAlloc</a>, la implementación de **XMemVirtualAlloc** tiene más flexibilidad para poder proporcionar un mayor rendimiento.

**XMemVirtualAlloc** también difiere de <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc">VirtualAlloc</a> en que la memoria obtenida a través de esta llamada de API está disponible de inmediato. Por el contrario, las direcciones de memoria devueltas por <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc">VirtualAlloc</a> se rellenarán con páginas físicas solo en el primer acceso, a través de una costosa operación de error de página.

Se espera que la memoria asignada con **XMemVirtualAlloc** se libere con <a href="https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualfree">VirtualFree</a>.

Las marcas de protección de página **PAGE\_NOCACHE** y **PAGE\_WRITECOMBINE** se fijan en el momento de la reserva de memoria y no se pueden cambiar durante una solicitud de confirmación posterior. Cualquier intento de cambiar el estado de una de estas marcas cuando se confirme la memoria se ignorará de forma silenciosa. La confirmación de memoria se realizará correctamente, pero la memoria tendrá el estado original de estas marcas.

Ejemplos:

```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);
```

## Requisitos

**Encabezado:** xmem.h

**Biblioteca:** xmem.lib

**Plataformas compatibles:** consolas de la familia XBOX One y consolas XBOX Series

## Consulte también

[Referencia de XMem](/es/reference/system/xmem/xmem_members)<br />[XMemMapPhysicalPages](/es/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

- [Trabajo con el administrador de memoria del sistema operativo de juego del Microsoft GDK](/es/build/console-features/memory/system-memory-working.md)
- [XMemVirtualQuery](/es/reference/system/xmem/functions/xmemvirtualquery.md)
- [XMemMapPhysicalPages](/es/reference/system/xmem/functions/xmemmapphysicalpages.md)
- [XMemMapPhysicalPagesScatter](/es/reference/system/xmem/functions/xmemmapphysicalpagesscatter.md)
- [XMEM_OPTIONS](/es/reference/system/xmem/enums/xmem_options.md)
