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