RtlCreateHeap 함수(ntifs.h)
RtlCreateHeap 루틴은 호출 프로세스에서 사용할 수 있는 힙 개체를 만듭니다. 이 루틴은 프로세스의 가상 주소 공간에 공간을 예약하고 이 블록의 지정된 초기 부분에 대한 실제 스토리지를 할당합니다.
통사론
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
);
매개 변수
[in] Flags
힙의 선택적 특성을 지정하는 플래그입니다. 이러한 옵션은 힙 함수(RtlAllocateHeap 및 RtlFreeHeap)에 대한 호출을 통해 새 힙에 대한 후속 액세스에 영향을 줍니다.
선택적 특성이 요청되지 않은 경우 호출자는 이 매개 변수를 0으로 설정해야 합니다.
이 매개 변수는 다음 값 중 하나 이상일 수 있습니다.
값 | 의미 |
---|---|
HEAP_GENERATE_EXCEPTIONS | 시스템에서 NULL을 반환하는 대신 STATUS_NO_MEMORY 같은 예외를 발생시켜 힙 오류를 표시하도록 지정합니다. |
HEAP_GROWABLE | 힙을 확장할 수 있도록 지정합니다. HeapBase NULL인 경우 지정해야 합니다. |
HEAP_NO_SERIALIZE | 힙 함수가 이 힙에서 메모리를 할당하고 해제할 때 상호 제외가 사용되지 않도록 지정합니다. HEAP_NO_SERIALIZE 지정되지 않은 경우 기본값은 힙에 대한 액세스를 직렬화하는 것입니다. 힙 액세스를 직렬화하면 두 개 이상의 스레드가 동시에 동일한 힙에서 메모리를 할당하고 해제할 수 있습니다. |
[in, optional] HeapBase
다음 두 작업 중 하나를 지정합니다.
HeapBase NULL이 아닌 값인 경우 힙에 사용할 호출자 할당 메모리 블록의 기본 주소를 지정합니다.
HeapBase NULL인 경우 RtlCreateHeap 프로세스의 가상 주소 공간에서 힙에 대한 시스템 메모리를 할당합니다.
[in, optional] ReserveSize
ReserveSize 0이 아닌 값인 경우 힙에 대해 예약할 초기 메모리 양(바이트)을 지정합니다. RtlCreateHeapReserveSize 다음 페이지 경계까지 반올림한 다음 힙에 대해 해당 크기의 블록을 예약합니다.
이 매개 변수는 선택 사항이며 0일 수 있습니다. 다음 표에서는 ReserveSize 및 CommitSize 매개 변수의 상호 작용을 요약합니다.
값 | 결과 |
---|---|
ReserveSize 0, CommitSize 0 | 64페이지는 처음에 힙용으로 예약됩니다. 한 페이지가 처음에 커밋됩니다. |
ReserveSize 0, CommitSize 0이 아닌 값 | RtlCreateHeapReserveSizeCommitSize같게 설정한 다음 ReserveSize 가장 가까운 배수(PAGE_SIZE * 16)로 반올림합니다. |
ReserveSize 0이 아닌 CommitSize 0 | 처음에는 힙에 대해 한 페이지가 커밋됩니다. |
ReserveSize 0이 아닌 CommitSize 0이 아닌 값 | CommitSizeReserveSize보다 크면 RtlCreateHeapCommitSizeReserveSize줄입니다. |
[in, optional] CommitSize
CommitSize 0이 아닌 값인 경우 힙에 커밋할 초기 메모리 양을 바이트 단위로 지정합니다. RtlCreateHeapCommitSize 다음 페이지 경계까지 반올림한 다음 힙에 대한 프로세스의 가상 주소 공간에서 해당 크기의 블록을 커밋합니다.
이 매개 변수는 선택 사항이며 0일 수 있습니다.
[in, optional] Lock
리소스 잠금으로 사용할 불투명 ERESOURCE 구조체에 대한 포인터입니다. 이 매개 변수는 선택 사항이며 NULL일 수 있습니다. 호출자가 제공하는 경우 구조체는 페이지가 없는 풀에서 할당되고
[in, optional] Parameters
힙을 만들 때 적용할 매개 변수가 포함된 RTL_HEAP_PARAMETERS 구조체에 대한 포인터입니다. 이 매개 변수는 선택 사항이며 NULL일 수 있습니다.
반환 값
RtlCreateHeap 만든 힙에 액세스하는 데 사용할 핸들을 반환합니다.
발언
RtlCreateHeap 호출 프로세스에서 RtlAllocateHeap호출하여 메모리 블록을 할당할 수 있는 프라이빗 힙 개체를 만듭니다. 초기 커밋 크기는 힙에 대해 처음에 할당된 페이지 수를 결정합니다. 초기 예약 크기는 힙에 대해 처음에 예약된 페이지 수를 결정합니다. 예약되었지만 커밋되지 않은 페이지는 힙이 확장될 수 있는 프로세스의 가상 주소 공간에 블록을 만듭니다.
RtlAllocateHeap에서 수행한 할당 요청이 힙의 초기 커밋 크기를 초과할 경우 시스템은 힙의 최대 크기까지 힙에 대한 물리적 스토리지의 추가 페이지를 커밋합니다. 힙을 공진할 수 있는 경우 최대 크기는 초기 예약 크기로 제한됩니다.
힙을 확장할 수 있는 경우 해당 크기는 사용 가능한 메모리에 의해서만 제한됩니다. RtlAllocateHeap의 요청이 커밋된 페이지의 현재 크기를 초과할 경우 시스템은 ZwAllocateVirtualMemory 호출하여 실제 스토리지를 사용할 수 있다고 가정하고 필요한 메모리를 가져옵니다.
또한 힙을 공진할 수 있는 경우 절대 제한이 발생합니다. 힙의 메모리 블록 최대 크기는 0x7F000 바이트입니다. 힙의 가상 메모리 임계값은 매개 변수 구조체의 최대 힙 블록 크기 또는 VirtualMemoryThreshold 멤버의 값과 같습니다. 또한 힙은 메타데이터 및 맞춤을 위해 요청 크기를 채워야 할 수 있으므로 힙의 최대 크기가 블록을 포함할 만큼 큰 경우에도 VirtualMemoryThreshold 4096바이트(1페이지) 내에 블록을 할당하는 요청이 실패할 수 있습니다. VirtualMemoryThreshold
힙을 확장할 수 있는 경우 힙의 가상 메모리 임계값보다 큰 블록을 할당하라는 요청은 자동으로 실패하지 않습니다. 시스템은 ZwAllocateVirtualMemory 호출하여 이러한 큰 블록에 필요한 메모리를 가져옵니다.
프라이빗 힙 개체의 메모리는 해당 개체를 만든 프로세스에서만 액세스할 수 있습니다.
시스템은 프라이빗 힙의 메모리를 사용하여 힙 지원 구조를 저장하므로 지정된 힙 크기를 모두 프로세스에 사용할 수 있는 것은 아닙니다. 예를 들어 RtlAllocateHeap 최대 크기가 64K인 힙에서 64K(K)를 요청하는 경우 시스템 오버헤드로 인해 요청이 실패할 수 있습니다.
HEAP_NO_SERIALIZE 지정되지 않은 경우(단순 기본값) 힙은 호출 프로세스 내에서 액세스를 직렬화합니다. 직렬화는 둘 이상의 스레드가 동일한 힙에서 블록을 동시에 할당하거나 해제하려고 할 때 상호 배제를 보장합니다. 직렬화에는 성능 비용이 적지만 여러 스레드가 동일한 힙에서 메모리를 할당하고 해제할 때마다 사용해야 합니다.
HEAP_NO_SERIALIZE 설정하면 힙에서 상호 배제가 제거됩니다. 직렬화가 없으면 동일한 힙 핸들을 사용하는 두 개 이상의 스레드가 동시에 메모리를 할당하거나 해제하려고 시도할 수 있으며, 이로 인해 힙이 손상될 수 있습니다. 따라서 HEAP_NO_SERIALIZE 다음 상황에서만 안전하게 사용할 수 있습니다.
프로세스에는 스레드가 하나뿐입니다.
프로세스에는 여러 스레드가 있지만 한 스레드만 특정 힙에 대한 힙 함수를 호출합니다.
프로세스에는 여러 스레드가 있으며 애플리케이션은 특정 힙에 대한 상호 배제를 위한 고유한 메커니즘을 제공합니다.
메모
액세스 위반을 방지하려면 구조적 예외 처리를 사용하여 힙에 쓰거나 읽는 코드를 보호합니다. 메모리 액세스를 사용한 구조적 예외 처리에 대한 자세한 내용은 예외 처리**참조하세요.
요구 사항
요구 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows XP |
대상 플랫폼 | 보편적 |
헤더 | ntifs.h(Ntifs.h 포함) |
라이브러리 | Ntoskrnl.lib |
DLL | NtosKrnl.exe(커널 모드); Ntdll.dll(사용자 모드) |
IRQL |
< DISPATCH_LEVEL |