Compartir a través de


Función RtlCreateHeap (ntifs.h)

La rutina RtlCreateHe ap crea un objeto de montón que el proceso de llamada puede usar. Esta rutina reserva espacio en el espacio de direcciones virtuales del proceso y asigna almacenamiento físico para una parte inicial especificada de este bloque.

Sintaxis

NTSYSAPI PVOID RtlCreateHeap(
  [in]           ULONG                Flags,
  [in, optional] PVOID                HeapBase,
  [in, optional] SIZE_T               ReserveSize,
  [in, optional] SIZE_T               CommitSize,
  [in, optional] PVOID                Lock,
  [in, optional] PRTL_HEAP_PARAMETERS Parameters
);

Parámetros

[in] Flags

Marcas que especifican atributos opcionales del montón. Estas opciones afectan al acceso posterior al nuevo montón a través de llamadas a las funciones del montón (RtlAllocateHeap y RtlFreeHeap).

Los autores de llamadas deben establecer este parámetro en cero si no se solicita ningún atributo opcional.

Este parámetro puede ser uno o varios de los siguientes valores.

Valor Significado
HEAP_GENERATE_EXCEPTIONS Especifica que el sistema indicará un error de montón mediante la generación de una excepción, como STATUS_NO_MEMORY, en lugar de devolver NULL.
HEAP_GROWABLE Especifica que el montón se puede crecer. Debe especificarse si heapBase es NULL.
HEAP_NO_SERIALIZE Especifica que la exclusión mutua no se usará cuando las funciones del montón asignen y liberen memoria de este montón. El valor predeterminado, cuando no se especifica HEAP_NO_SERIALIZE, es serializar el acceso al montón. La serialización del acceso al montón permite que dos o más subprocesos asignen y liberen memoria simultáneamente del mismo montón.

[in, optional] HeapBase

Especifica una de estas dos acciones:

Si HeapBase es un valor distinto de NULL, especifica la dirección base de un bloque de memoria asignada por el autor de la llamada que se usará para el montón.

Si HeapBase es NULL, RtlCreateHeap asigna memoria del sistema para el montón desde el espacio de direcciones virtual del proceso.

[in, optional] ReserveSize

Si reserveSize es un valor distinto de cero, especifica la cantidad inicial de memoria, en bytes, que se va a reservar para el montón. RtlCreateHeap redondea ReserveSize hasta el límite de la página siguiente y, a continuación, reserva un bloque de ese tamaño para el montón.

Este parámetro es opcional y puede ser cero. En la tabla siguiente se resume la interacción de los parámetros ReserveSize y CommitSize.

Valores Resultado
ReserveSize cero, CommitSize cero Inicialmente se reservan 64 páginas para el montón. Se confirma inicialmente una página.
ReserveSize cero, CommitSize nonzero RtlCreateHeap establece ReserveSize igual a CommitSizey, a continuación, redondea ReserveSize hasta el múltiplo más cercano (PAGE_SIZE * 16).
ReserveSize distinto de cero, CommitSize cero Una página se confirma inicialmente para el montón.
ReserveSize distinto de cero, CommitSize nonzero Si CommitSize es mayor que ReserveSize, RtlCreateHeap reduce CommitSize a ReserveSize.

[in, optional] CommitSize

Si CommitSize es un valor distinto de cero, especifica la cantidad inicial de memoria, en bytes, que se va a confirmar para el montón. RtlCreateHeap redondea CommitSize hasta el límite de página siguiente y, a continuación, confirma un bloque de ese tamaño en el espacio de direcciones virtuales del proceso para el montón.

Este parámetro es opcional y puede ser cero.

[in, optional] Lock

Puntero a una estructura ERESOURCE opaca que se usará como bloqueo de recursos. Este parámetro es opcional y puede ser NULL. Cuando lo proporciona el autor de la llamada, la estructura debe asignarse desde un grupo no paginado e inicializarse llamando a ExInitializeResourceLite o ExReinitializeResourceLite. Si se establece la marca HEAP_NO_SERIALIZE, este parámetro debe ser NULL.

[in, optional] Parameters

Puntero a una estructura de RTL_HEAP_PARAMETERS que contiene parámetros que se van a aplicar al crear el montón. Este parámetro es opcional y puede ser NULL.

Valor devuelto

RtlCreateHeap devuelve un identificador que se usará para acceder al montón creado.

Observaciones

RtlCreateHeap crea un objeto de montón privado desde el que el proceso de llamada puede asignar bloques de memoria llamando a RtlAllocateHeap. El tamaño de confirmación inicial determina el número de páginas que se asignan inicialmente para el montón. El tamaño de reserva inicial determina el número de páginas que se reservan inicialmente para el montón. Las páginas reservadas pero sin confirmar crean un bloque en el espacio de direcciones virtuales del proceso en el que el montón se puede expandir.

Si las solicitudes de asignación realizadas por RtlAllocateHeap superan el tamaño de confirmación inicial del montón, el sistema confirma páginas adicionales de almacenamiento físico para el montón, hasta el tamaño máximo del montón. Si el montón no se puede crecer, su tamaño máximo se limita a su tamaño de reserva inicial.

Si el montón se puede crecer, su tamaño solo está limitado por la memoria disponible. Si las solicitudes de RtlAllocateHeap superan el tamaño actual de las páginas confirmadas, el sistema llama a ZwAllocateVirtualMemory para obtener la memoria necesaria, suponiendo que el almacenamiento físico esté disponible.

Además, si el montón no se puede crecer, surge una limitación absoluta: el tamaño máximo de un bloque de memoria del montón es 0x7F000 bytes. El umbral de memoria virtual del montón es igual al tamaño máximo del bloque de montón o al valor de la VirtualMemoryThreshold miembro de la estructura Parameters, lo que sea menor. El montón también puede necesitar rellenar el tamaño de la solicitud con fines de metadatos y alineación, por lo que las solicitudes para asignar bloques dentro de 4096 Bytes (1 página) del VirtualMemoryThreshold pueden producir un error incluso si el tamaño máximo del montón es lo suficientemente grande como para contener el bloque. (Para obtener más información sobre virtualMemoryThreshold, consulte los miembros del parámetro Parameters para RtlCreateHeap).

Si el montón se puede crecer, las solicitudes para asignar bloques mayores que el umbral de memoria virtual del montón no fallan automáticamente; el sistema llama a ZwAllocateVirtualMemory para obtener la memoria necesaria para estos bloques grandes.

La memoria de un objeto de montón privado solo es accesible para el proceso que lo creó.

El sistema usa memoria del montón privado para almacenar estructuras compatibles con el montón, por lo que no todo el tamaño del montón especificado está disponible para el proceso. Por ejemplo, si RtlAllocateHeap solicita 64 kilobytes (K) desde un montón con un tamaño máximo de 64K, la solicitud puede producir un error debido a la sobrecarga del sistema.

Si no se especifica HEAP_NO_SERIALIZE (el valor predeterminado simple), el montón serializará el acceso dentro del proceso de llamada. La serialización garantiza la exclusión mutua cuando dos o más subprocesos intentan asignar o liberar bloques simultáneamente del mismo montón. Hay un pequeño costo de rendimiento para la serialización, pero se debe usar cada vez que varios subprocesos asignan y liberan memoria del mismo montón.

Establecer HEAP_NO_SERIALIZE elimina la exclusión mutua en el montón. Sin serialización, dos o más subprocesos que usan el mismo identificador de montón podrían intentar asignar o liberar memoria simultáneamente, lo que probablemente causaría daños en el montón. Por lo tanto, HEAP_NO_SERIALIZE solo se puede usar de forma segura en las situaciones siguientes:

  • El proceso solo tiene un subproceso.

  • El proceso tiene varios subprocesos, pero solo un subproceso llama a las funciones del montón para un montón específico.

  • El proceso tiene varios subprocesos y la aplicación proporciona su propio mecanismo para la exclusión mutua a un montón específico.

Nota

Para protegerse contra una infracción de acceso, use el control de excepciones estructurados para proteger cualquier código que escriba en un montón o lea desde él. Para obtener más información sobre el control estructurado de excepciones con accesos a memoria, vea Control de excepciones**.

Requisitos

Requisito Valor
cliente mínimo admitido Windows XP
de la plataforma de destino de Universal
encabezado de ntifs.h (incluya Ntifs.h)
biblioteca de Ntoskrnl.lib
DLL de NtosKrnl.exe (modo kernel); Ntdll.dll (modo de usuario)
irQL < DISPATCH_LEVEL

Consulte también

rtlAllocateHeap

RtlDestroyHeap

RtlFreeHeap