Funzione RtlCreateHeap (ntifs.h)
La routine RtlCreateHeap crea un oggetto heap che può essere usato dal processo di chiamata. Questa routine riserva spazio nello spazio indirizzi virtuale del processo e alloca l'archiviazione fisica per una parte iniziale specificata di questo blocco.
Sintassi
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
);
Parametri
[in] Flags
Flag che specificano attributi facoltativi dell'heap. Queste opzioni influiscono sull'accesso successivo al nuovo heap tramite chiamate alle funzioni heap (RtlAllocateHeap e RtlFreeHeap).
I chiamanti devono impostare questo parametro su zero se non sono richiesti attributi facoltativi.
Questo parametro può essere uno o più dei valori seguenti.
Valore | Significato |
---|---|
HEAP_GENERATE_EXCEPTIONS | Specifica che il sistema indicherà un errore heap generando un'eccezione, ad esempio STATUS_NO_MEMORY, anziché restituire NULL. |
HEAP_GROWABLE | Specifica che l'heap è cresciuto. Deve essere specificato se HeapBase è NULL. |
HEAP_NO_SERIALIZE | Specifica che l'esclusione reciproca non verrà usata quando le funzioni heap allocano e liberano memoria da questo heap. Il valore predefinito, quando HEAP_NO_SERIALIZE non è specificato, consiste nel serializzare l'accesso all'heap. La serializzazione dell'accesso heap consente a due o più thread di allocare e liberare la memoria contemporaneamente dallo stesso heap. |
[in, optional] HeapBase
Specifica una delle due azioni seguenti:
Se HeapBase è un valore non NULL, specifica l'indirizzo di base per un blocco di memoria allocata dal chiamante da usare per l'heap.
Se HeapBase è NULL, RtlCreateHeap alloca la memoria di sistema per l'heap dallo spazio indirizzi virtuale del processo.
[in, optional] ReserveSize
Se ReserveSize è un valore diverso da zero, specifica la quantità iniziale di memoria, in byte, per riservare l'heap. RtlCreateHeap arrotonda ReserveSize fino al limite della pagina successiva e quindi riserva un blocco di tale dimensione per l'heap.
Questo parametro è facoltativo e può essere zero. La tabella seguente riepiloga l'interazione dei parametri ReserveSize e CommitSize .
Valori | Risultato |
---|---|
ReserveSize zero, CommitSize zero | 64 pagine sono inizialmente riservate all'heap. Viene inizialmente eseguito il commit di una pagina. |
ReserveSize zero, CommitSize nonzero | RtlCreateHeap imposta ReserveSize come uguale a CommitSize e quindi esegue il round ReserveSize fino al multiplo più vicino (PAGE_SIZE * 16). |
ReserveSize non zero, CommitSize zero | Una pagina viene inizialmente eseguita per l'heap. |
ReserveSize nonzero, CommitSize nonzero | Se CommitSize è maggiore di ReserveSize, RtlCreateHeap riduce CommitSize in ReserveSize. |
[in, optional] CommitSize
Se CommitSize è un valore diverso da zero, specifica la quantità iniziale di memoria, in byte, per eseguire il commit per l'heap. RtlCreateHeap esegue l'roundSize fino al limite della pagina successiva e quindi esegue il commit di un blocco di tale dimensione nello spazio indirizzi virtuale del processo per l'heap.
Questo parametro è facoltativo e può essere zero.
[in, optional] Lock
Puntatore a una struttura ERESOURCE opaca da usare come blocco di risorse. Questo parametro è facoltativo e può essere NULL. Se fornito dal chiamante, la struttura deve essere allocata dal pool non con pagine e inizializzata chiamando ExInitializeResourceLite o ExReinitializeResourceLite. Se il flag di HEAP_NO_SERIALIZE è impostato, questo parametro deve essere NULL.
[in, optional] Parameters
Puntatore a una struttura RTL_HEAP_PARAMETERS che contiene parametri da applicare durante la creazione dell'heap. Questo parametro è facoltativo e può essere NULL.
Valore restituito
RtlCreateHeap restituisce un handle da usare per accedere all'heap creato.
Commenti
RtlCreateHeap crea un oggetto heap privato da cui il processo chiamante può allocare blocchi di memoria chiamando RtlAllocateHeap. Le dimensioni iniziali del commit determinano il numero di pagine inizialmente allocate per l'heap. La dimensione iniziale della riserva determina il numero di pagine inizialmente riservate per l'heap. Le pagine riservate ma non inviate creano un blocco nello spazio indirizzi virtuale del processo in cui è possibile espandere l'heap.
Se le richieste di allocazione effettuate da RtlAllocateHeap superano le dimensioni iniziali del commit dell'heap, il sistema esegue il commit di pagine aggiuntive dell'archiviazione fisica per l'heap, fino alla dimensione massima dell'heap. Se l'heap non è scalabile, la dimensione massima è limitata alla dimensione iniziale della riserva.
Se l'heap è cresciuto, le dimensioni sono limitate solo dalla memoria disponibile. Se le richieste da RtlAllocateHeap superano le dimensioni correnti delle pagine commit, il sistema chiama ZwAllocateVirtualMemory per ottenere la memoria necessaria, presupponendo che l'archiviazione fisica sia disponibile.
Inoltre, se l'heap non èrowable, si verifica una limitazione assoluta: la dimensione massima di un blocco di memoria nell'heap è 0x7F000 byte. La soglia di memoria virtuale dell'heap è uguale alla dimensione massima del blocco heap o al valore del membro VirtualMemoryThreshold della struttura Parameters , minore. L'heap potrebbe anche dover inserire le dimensioni della richiesta per i metadati e gli scopi di allineamento in modo che le richieste di allocare blocchi entro 4096 byte (1 pagina) di VirtualMemoryThreshold potrebbero non riuscire anche se la dimensione massima dell'heap è sufficiente per contenere il blocco. Per altre informazioni su VirtualMemoryThreshold, vedere i membri del parametro Parameters su RtlCreateHeap.
Se l'heap è scalabile, le richieste di allocare blocchi più grandi della soglia di memoria virtuale dell'heap non hanno esito negativo automaticamente; il sistema chiama ZwAllocateVirtualMemory per ottenere la memoria necessaria per blocchi di grandi dimensioni.
La memoria di un oggetto heap privato è accessibile solo al processo creato.
Il sistema usa la memoria dall'heap privato per archiviare strutture di supporto heap, quindi non tutte le dimensioni dell'heap specificate sono disponibili per il processo. Ad esempio, se RtlAllocateHeap richiede 64 kilobyte (K) da un heap con dimensioni massime di 64K, la richiesta potrebbe non riuscire a causa del sovraccarico del sistema.
Se HEAP_NO_SERIALIZE non è specificato (impostazione predefinita semplice), l'heap serializzerà l'accesso all'interno del processo di chiamata. La serializzazione garantisce l'esclusione reciproca quando due o più thread tentano di allocare o liberare contemporaneamente blocchi dallo stesso heap. È previsto un costo di prestazioni ridotto per la serializzazione, ma deve essere usato ogni volta che più thread allocano e liberano memoria dallo stesso heap.
L'impostazione HEAP_NO_SERIALIZE elimina l'esclusione reciproca nell'heap. Senza serializzazione, due o più thread che usano lo stesso handle heap potrebbero tentare di allocare o liberare memoria contemporaneamente, causando probabilmente danneggiamenti nell'heap. Pertanto, HEAP_NO_SERIALIZE può essere usato in modo sicuro solo nelle situazioni seguenti:
Il processo ha un solo thread.
Il processo include più thread, ma solo un thread chiama le funzioni heap per un heap specifico.
Il processo include più thread e l'applicazione fornisce il proprio meccanismo per l'esclusione reciproca a un heap specifico.
Nota
Per proteggere una violazione di accesso, usare la gestione delle eccezioni strutturate per proteggere qualsiasi codice che scrive in o legge da un heap. Per altre informazioni sulla gestione delle eccezioni strutturate con gli accessi alla memoria, vedere Gestione delle eccezioni**.
Requisiti
Requisito | Valore |
---|---|
Client minimo supportato | Windows XP |
Piattaforma di destinazione | Universale |
Intestazione | ntifs.h (include Ntifs.h) |
Libreria | Ntoskrnl.lib |
DLL | NtosKrnl.exe (modalità kernel); Ntdll.dll (modalità utente) |
IRQL | < DISPATCH_LEVEL |